diff options
Diffstat (limited to 'drivers/net/wireless')
411 files changed, 23482 insertions, 21534 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1c008c61b95..ddc061dd150 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -1869,7 +1869,7 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) static void try_auto_wep(struct airo_info *ai) { - if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) { + if (auto_wep && !test_bit(FLAG_RADIO_DOWN, &ai->flags)) { ai->expires = RUN_AT(3*HZ); wake_up_interruptible(&ai->thr_wait); } diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index efc01110dc3..c54b7d37bff 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -174,28 +174,24 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); -extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...); - -#define _ath_printk(level, common, fmt, ...) \ -do { \ - __always_unused struct ath_common *unused = common; \ - ath_printk(level, fmt, ##__VA_ARGS__); \ -} while (0) +__printf(3, 4) +void ath_printk(const char *level, const struct ath_common *common, + const char *fmt, ...); #define ath_emerg(common, fmt, ...) \ - _ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_EMERG, common, fmt, ##__VA_ARGS__) #define ath_alert(common, fmt, ...) \ - _ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_ALERT, common, fmt, ##__VA_ARGS__) #define ath_crit(common, fmt, ...) \ - _ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_CRIT, common, fmt, ##__VA_ARGS__) #define ath_err(common, fmt, ...) \ - _ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_ERR, common, fmt, ##__VA_ARGS__) #define ath_warn(common, fmt, ...) \ - _ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_WARNING, common, fmt, ##__VA_ARGS__) #define ath_notice(common, fmt, ...) \ - _ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_NOTICE, common, fmt, ##__VA_ARGS__) #define ath_info(common, fmt, ...) \ - _ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) + ath_printk(KERN_INFO, common, fmt, ##__VA_ARGS__) /** * enum ath_debug_level - atheros wireless debug level @@ -256,7 +252,7 @@ enum ATH_DEBUG { #define ath_dbg(common, dbg_mask, fmt, ...) \ do { \ if ((common)->debug_mask & ATH_DBG_##dbg_mask) \ - _ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ + ath_printk(KERN_DEBUG, common, fmt, ##__VA_ARGS__); \ } while (0) #define ATH_DBG_WARN(foo, arg...) WARN(foo, arg) diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index ee7ea572b06..8faa129da5a 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -140,23 +140,23 @@ static int ath_ahb_probe(struct platform_device *pdev) if (bcfg->devid >= AR5K_SREV_AR2315_R6) { /* Enable WMAC AHB arbitration */ - reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; - __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); /* Enable global WMAC swapping */ - reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP); + reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP); reg |= AR5K_AR2315_BYTESWAP_WMAC; - __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); + iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); } else { /* Enable WMAC DMA access (assuming 5312 or 231x*/ /* TODO: check other platforms */ - reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE); + reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); if (to_platform_device(ah->dev)->id == 0) reg |= AR5K_AR5312_ENABLE_WLAN0; else reg |= AR5K_AR5312_ENABLE_WLAN1; - __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); + iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); /* * On a dual-band AR5312, the multiband radio is only @@ -203,17 +203,17 @@ static int ath_ahb_remove(struct platform_device *pdev) if (bcfg->devid >= AR5K_SREV_AR2315_R6) { /* Disable WMAC AHB arbitration */ - reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; - __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); + iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); } else { /*Stop DMA access */ - reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE); + reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); if (to_platform_device(ah->dev)->id == 0) reg &= ~AR5K_AR5312_ENABLE_WLAN0; else reg &= ~AR5K_AR5312_ENABLE_WLAN1; - __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE); + iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); } ath5k_deinit_ah(ah); diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index bf674161a21..35e93704c4e 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -257,7 +257,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, "beacon RSSI high"); /* only OFDM: beacon RSSI is high, we can disable ODFM weak * signal detection */ - if (ofdm_trigger && as->ofdm_weak_sig == true) { + if (ofdm_trigger && as->ofdm_weak_sig) { ath5k_ani_set_ofdm_weak_signal_detection(ah, false); ath5k_ani_set_spur_immunity_level(ah, 0); return; @@ -272,7 +272,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, * but can raise firstep level */ ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "beacon RSSI mid"); - if (ofdm_trigger && as->ofdm_weak_sig == false) + if (ofdm_trigger && !as->ofdm_weak_sig) ath5k_ani_set_ofdm_weak_signal_detection(ah, true); if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) ath5k_ani_set_firstep_level(ah, as->firstep_level + 1); @@ -282,7 +282,7 @@ ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, * detect and zero firstep level to maximize CCK sensitivity */ ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "beacon RSSI low, 2GHz"); - if (ofdm_trigger && as->ofdm_weak_sig == true) + if (ofdm_trigger && as->ofdm_weak_sig) ath5k_ani_set_ofdm_weak_signal_detection(ah, false); if (as->firstep_level > 0) ath5k_ani_set_firstep_level(ah, 0); @@ -326,7 +326,7 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) { /* beacon RSSI is mid-range: turn on ODFM weak signal * detection and next, lower firstep level */ - if (as->ofdm_weak_sig == false) { + if (!as->ofdm_weak_sig) { ath5k_ani_set_ofdm_weak_signal_detection(ah, true); return; diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index c2b2518c2ec..8d434b8f585 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1320,6 +1320,7 @@ struct ath5k_hw { struct ieee80211_vif *bslot[ATH_BCBUF]; u16 num_ap_vifs; u16 num_adhoc_vifs; + u16 num_mesh_vifs; unsigned int bhalq, /* SW q for outgoing beacons */ bmisscount, /* missed beacon transmits */ bintval, /* beacon interval in TU */ @@ -1656,12 +1657,12 @@ static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) { - return __raw_readl(ath5k_ahb_reg(ah, reg)); + return ioread32(ath5k_ahb_reg(ah, reg)); } static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) { - __raw_writel(val, ath5k_ahb_reg(ah, reg)); + iowrite32(val, ath5k_ahb_reg(ah, reg)); } #else diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d366dadcf86..0e643b016b3 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -80,7 +80,7 @@ static bool modparam_fastchanswitch; module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); -static int ath5k_modparam_no_hw_rfkill_switch; +static bool ath5k_modparam_no_hw_rfkill_switch; module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, bool, S_IRUGO); MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); @@ -1867,7 +1867,8 @@ ath5k_beacon_send(struct ath5k_hw *ah) ah->bmisscount = 0; } - if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) || + if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + + ah->num_mesh_vifs > 1) || ah->opmode == NL80211_IFTYPE_MESH_POINT) { u64 tsf = ath5k_hw_get_tsf64(ah); u32 tsftu = TSF_TO_TU(tsf); @@ -1952,7 +1953,8 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) u64 hw_tsf; intval = ah->bintval & AR5K_BEACON_PERIOD; - if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs > 1) { + if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + + ah->num_mesh_vifs > 1) { intval /= ATH_BCBUF; /* staggered multi-bss beacons */ if (intval < 15) ATH5K_WARN(ah, "intval %u is too low, min 15\n", @@ -2330,15 +2332,6 @@ ath5k_calibrate_work(struct work_struct *work) "got new rfgain, resetting\n"); ieee80211_queue_work(ah->hw, &ah->reset_work); } - - /* TODO: On full calibration we should stop TX here, - * so that it doesn't interfere (mostly due to gain_f - * calibration that messes with tx packets -see phy.c). - * - * NOTE: Stopping the queues from above is not enough - * to stop TX but saves us from disconecting (at least - * we don't lose packets). */ - ieee80211_stop_queues(ah->hw); } else ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; @@ -2353,10 +2346,9 @@ ath5k_calibrate_work(struct work_struct *work) ah->curchan->center_freq)); /* Clear calibration flags */ - if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { - ieee80211_wake_queues(ah->hw); + if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; - } else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) + else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; } @@ -2442,6 +2434,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + /* SW support for IBSS_RSN is provided by mac80211 */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + /* both antennas can be configured as RX or TX */ hw->wiphy->available_antennas_tx = 0x3; hw->wiphy->available_antennas_rx = 0x3; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 6ed4c0717e3..5c532995541 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -134,6 +134,8 @@ ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ah->num_ap_vifs++; else if (avf->opmode == NL80211_IFTYPE_ADHOC) ah->num_adhoc_vifs++; + else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) + ah->num_mesh_vifs++; } /* Any MAC address is fine, all others are included through the @@ -175,6 +177,8 @@ ath5k_remove_interface(struct ieee80211_hw *hw, ah->num_ap_vifs--; else if (avf->opmode == NL80211_IFTYPE_ADHOC) ah->num_adhoc_vifs--; + else if (avf->opmode == NL80211_IFTYPE_MESH_POINT) + ah->num_mesh_vifs--; ath5k_update_bssid_mask_and_opmode(ah, NULL); mutex_unlock(&ah->lock); @@ -483,6 +487,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; + if (vif->type == NL80211_IFTYPE_ADHOC && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* don't program group keys when using IBSS_RSN */ + return -EOPNOTSUPP; + } + switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index e1f8613426a..3a2845489a1 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1871,31 +1871,15 @@ ath5k_hw_phy_calibrate(struct ath5k_hw *ah, ret = 0; } - /* On full calibration do an AGC calibration and - * request a PAPD probe for gainf calibration if - * needed */ - if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) { - - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL); - - ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF, - 0, false); - if (ret) { - ATH5K_ERR(ah, - "gain calibration timeout (%uMHz)\n", - channel->center_freq); - } - - if ((ah->ah_radio == AR5K_RF5111 || - ah->ah_radio == AR5K_RF5112) - && (channel->hw_value != AR5K_MODE_11B)) - ath5k_hw_request_rfgain_probe(ah); - } - - /* Update noise floor - * XXX: Only do this after AGC calibration */ + /* On full calibration request a PAPD probe for + * gainf calibration if needed */ + if ((ah->ah_cal_mask & AR5K_CALIBRATION_FULL) && + (ah->ah_radio == AR5K_RF5111 || + ah->ah_radio == AR5K_RF5112) && + channel->hw_value != AR5K_MODE_11B) + ath5k_hw_request_rfgain_probe(ah); + + /* Update noise floor */ if (!(ah->ah_cal_mask & AR5K_CALIBRATION_NF)) ath5k_hw_update_noise_floor(ah); diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 250db40b751..200f165c0c6 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -473,14 +473,14 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) } /* Put BB/MAC into reset */ - regval = __raw_readl(reg); - __raw_writel(regval | val, reg); - regval = __raw_readl(reg); + regval = ioread32(reg); + iowrite32(regval | val, reg); + regval = ioread32(reg); usleep_range(100, 150); /* Bring BB/MAC out of reset */ - __raw_writel(regval & ~val, reg); - regval = __raw_readl(reg); + iowrite32(regval & ~val, reg); + regval = ioread32(reg); /* * Reset configuration register (for hw byte-swap). Note that this diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index 3d5f8be20ea..d755a5e7ed2 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -1,12 +1,29 @@ config ATH6KL - tristate "Atheros ath6kl support" + tristate "Atheros mobile chipsets support" + +config ATH6KL_SDIO + tristate "Atheros ath6kl SDIO support" + depends on ATH6KL depends on MMC depends on CFG80211 ---help--- This module adds support for wireless adapters based on - Atheros AR6003 chipset running over SDIO. If you choose to - build it as a module, it will be called ath6kl. Pls note - that AR6002 and AR6001 are not supported by this driver. + Atheros AR6003 and AR6004 chipsets running over SDIO. If you + choose to build it as a module, it will be called ath6kl_sdio. + Please note that AR6002 and AR6001 are not supported by this + driver. + +config ATH6KL_USB + tristate "Atheros ath6kl USB support" + depends on ATH6KL + depends on USB + depends on CFG80211 + depends on EXPERIMENTAL + ---help--- + This module adds support for wireless adapters based on + Atheros AR6004 chipset running over USB. This is still under + implementation and it isn't functional. If you choose to + build it as a module, it will be called ath6kl_usb. config ATH6KL_DEBUG bool "Atheros ath6kl debugging" diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 70706930355..85746c3eb02 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -1,5 +1,6 @@ #------------------------------------------------------------------------------ -# Copyright (c) 2004-2010 Atheros Communications Inc. +# Copyright (c) 2004-2011 Atheros Communications Inc. +# Copyright (c) 2011-2012 Qualcomm Atheros, Inc. # All rights reserved. # # @@ -21,17 +22,21 @@ # Author(s): ="Atheros" #------------------------------------------------------------------------------ -obj-$(CONFIG_ATH6KL) := ath6kl.o -ath6kl-y += debug.o -ath6kl-y += hif.o -ath6kl-y += htc.o -ath6kl-y += bmi.o -ath6kl-y += cfg80211.o -ath6kl-y += init.o -ath6kl-y += main.o -ath6kl-y += txrx.o -ath6kl-y += wmi.o -ath6kl-y += sdio.o -ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o +obj-$(CONFIG_ATH6KL) += ath6kl_core.o +ath6kl_core-y += debug.o +ath6kl_core-y += hif.o +ath6kl_core-y += htc.o +ath6kl_core-y += bmi.o +ath6kl_core-y += cfg80211.o +ath6kl_core-y += init.o +ath6kl_core-y += main.o +ath6kl_core-y += txrx.o +ath6kl_core-y += wmi.o +ath6kl_core-y += core.o +ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o -ccflags-y += -D__CHECK_ENDIAN__ +obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o +ath6kl_sdio-y += sdio.o + +obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o +ath6kl_usb-y += usb.o diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index bce3575c310..334dbd834b3 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -57,8 +58,14 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, return ret; } - ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, - sizeof(targ_info->version)); + if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, + sizeof(*targ_info)); + } else { + ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, + sizeof(targ_info->version)); + } + if (ret) { ath6kl_err("Unable to recv target info: %d\n", ret); return ret; @@ -99,7 +106,7 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, } ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n", - targ_info->version, targ_info->type); + targ_info->version, targ_info->type); return 0; } @@ -186,7 +193,7 @@ int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len) memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header); ath6kl_dbg(ATH6KL_DBG_BMI, - "bmi write memory: addr: 0x%x, len: %d\n", addr, len); + "bmi write memory: addr: 0x%x, len: %d\n", addr, len); len_remain = len; while (len_remain) { @@ -428,7 +435,7 @@ int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len) memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len)); offset += sizeof(tx_len); memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain], - tx_len); + tx_len); offset += tx_len; ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset); diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h index f1ca6812456..18fdd69e1f7 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.h +++ b/drivers/net/wireless/ath/ath6kl/bmi.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -222,6 +223,29 @@ struct ath6kl_bmi_target_info { __le32 type; /* target type */ } __packed; +#define ath6kl_bmi_write_hi32(ar, item, val) \ + ({ \ + u32 addr; \ + __le32 v; \ + \ + addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ + v = cpu_to_le32(val); \ + ath6kl_bmi_write(ar, addr, (u8 *) &v, sizeof(v)); \ + }) + +#define ath6kl_bmi_read_hi32(ar, item, val) \ + ({ \ + u32 addr, *check_type = val; \ + __le32 tmp; \ + int ret; \ + \ + (void) (check_type == val); \ + addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item)); \ + ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4); \ + *val = le32_to_cpu(tmp); \ + ret; \ + }) + int ath6kl_bmi_init(struct ath6kl *ar); void ath6kl_bmi_cleanup(struct ath6kl *ar); void ath6kl_bmi_reset(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 6c59a217b1a..00d38952b5f 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,6 +16,8 @@ */ #include <linux/moduleparam.h> +#include <linux/inetdevice.h> +#include <linux/export.h> #include "core.h" #include "cfg80211.h" @@ -22,10 +25,6 @@ #include "hif-ops.h" #include "testmode.h" -static unsigned int ath6kl_p2p; - -module_param(ath6kl_p2p, uint, 0644); - #define RATETAB_ENT(_rate, _rateid, _flags) { \ .bitrate = (_rate), \ .flags = (_flags), \ @@ -70,6 +69,10 @@ static struct ieee80211_rate ath6kl_rates[] = { #define ath6kl_g_rates (ath6kl_rates + 0) #define ath6kl_g_rates_size 12 +#define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ + IEEE80211_HT_CAP_SGI_20 | \ + IEEE80211_HT_CAP_SGI_40) + static struct ieee80211_channel ath6kl_2ghz_channels[] = { CHAN2G(1, 2412, 0), CHAN2G(2, 2417, 0), @@ -114,6 +117,8 @@ static struct ieee80211_supported_band ath6kl_band_2ghz = { .channels = ath6kl_2ghz_channels, .n_bitrates = ath6kl_g_rates_size, .bitrates = ath6kl_g_rates, + .ht_cap.cap = ath6kl_g_htcap, + .ht_cap.ht_supported = true, }; static struct ieee80211_supported_band ath6kl_band_5ghz = { @@ -121,6 +126,8 @@ static struct ieee80211_supported_band ath6kl_band_5ghz = { .channels = ath6kl_5ghz_a_channels, .n_bitrates = ath6kl_a_rates_size, .bitrates = ath6kl_a_rates, + .ht_cap.cap = ath6kl_g_htcap, + .ht_cap.ht_supported = true, }; #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */ @@ -196,7 +203,7 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif, break; default: - ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type); + ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type); return -ENOTSUPP; } @@ -383,7 +390,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, return false; if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) && - ar->num_vif)) + ar->num_vif)) return false; if (type == NL80211_IFTYPE_STATION || @@ -409,6 +416,12 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type, return false; } +static bool ath6kl_is_tx_pending(struct ath6kl *ar) +{ + return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0; +} + + static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { @@ -416,6 +429,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, struct ath6kl_vif *vif = netdev_priv(dev); int status; u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE; + u16 interval; ath6kl_cfg80211_sscan_disable(vif); @@ -452,8 +466,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, * sleep until the command queue drains */ wait_event_interruptible_timeout(ar->event_wq, - ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0, - WMI_TIMEOUT); + ath6kl_is_tx_pending(ar), + WMI_TIMEOUT); if (signal_pending(current)) { ath6kl_err("cmd queue drain timeout\n"); up(&ar->sem); @@ -461,13 +475,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } } - if (sme->ie && (sme->ie_len > 0)) { - status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); - if (status) { - up(&ar->sem); - return status; - } - } else + status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); + if (status) { + up(&ar->sem); + return status; + } + + if (sme->ie == NULL || sme->ie_len == 0) ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG; if (test_bit(CONNECTED, &vif->flags) && @@ -523,8 +537,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, (vif->prwise_crypto == WEP_CRYPT)) { struct ath6kl_key *key = NULL; - if (sme->key_idx < WMI_MIN_KEY_INDEX || - sme->key_idx > WMI_MAX_KEY_INDEX) { + if (sme->key_idx > WMI_MAX_KEY_INDEX) { ath6kl_err("key index %d out of bounds\n", sme->key_idx); up(&ar->sem); @@ -549,7 +562,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if (!ar->usr_bss_filter) { clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags); if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - ALL_BSS_FILTER, 0) != 0) { + ALL_BSS_FILTER, 0) != 0) { ath6kl_err("couldn't set bss filtering\n"); up(&ar->sem); return -EIO; @@ -571,6 +584,20 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, vif->grp_crypto_len, vif->ch_hint); vif->reconnect_flag = 0; + + if (vif->nw_type == INFRA_NETWORK) { + interval = max_t(u16, vif->listen_intvl_t, + ATH6KL_MAX_WOW_LISTEN_INTL); + status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + interval, + 0); + if (status) { + ath6kl_err("couldn't set listen intervel\n"); + up(&ar->sem); + return status; + } + } + status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type, vif->dot11_auth_mode, vif->auth_mode, vif->prwise_crypto, @@ -593,8 +620,8 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) && - ((vif->auth_mode == WPA_PSK_AUTH) - || (vif->auth_mode == WPA2_PSK_AUTH))) { + ((vif->auth_mode == WPA_PSK_AUTH) || + (vif->auth_mode == WPA2_PSK_AUTH))) { mod_timer(&vif->disconnect_timer, jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL)); } @@ -605,11 +632,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return 0; } -static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, - enum network_type nw_type, - const u8 *bssid, - struct ieee80211_channel *chan, - const u8 *beacon_ie, size_t beacon_ie_len) +static struct cfg80211_bss * +ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, + enum network_type nw_type, + const u8 *bssid, + struct ieee80211_channel *chan, + const u8 *beacon_ie, + size_t beacon_ie_len) { struct ath6kl *ar = vif->ar; struct cfg80211_bss *bss; @@ -638,7 +667,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, */ ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL); if (ie == NULL) - return -ENOMEM; + return NULL; ie[0] = WLAN_EID_SSID; ie[1] = vif->ssid_len; memcpy(ie + 2, vif->ssid, vif->ssid_len); @@ -652,15 +681,9 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, "cfg80211\n", bssid); kfree(ie); } else - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss " - "entry\n"); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); - if (bss == NULL) - return -ENOMEM; - - cfg80211_put_bss(bss); - - return 0; + return bss; } void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -672,6 +695,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, { struct ieee80211_channel *chan; struct ath6kl *ar = vif->ar; + struct cfg80211_bss *bss; /* capinfo + listen interval */ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); @@ -712,8 +736,9 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, chan = ieee80211_get_channel(ar->wiphy, (int) channel); - if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info, - beacon_ie_len) < 0) { + bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, + assoc_info, beacon_ie_len); + if (!bss) { ath6kl_err("could not add cfg80211 bss entry\n"); return; } @@ -722,6 +747,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", nw_type & ADHOC_CREATOR ? "creator" : "joiner"); cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); + cfg80211_put_bss(bss); return; } @@ -732,11 +758,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, assoc_req_ie, assoc_req_len, assoc_resp_ie, assoc_resp_len, WLAN_STATUS_SUCCESS, GFP_KERNEL); + cfg80211_put_bss(bss); } else if (vif->sme_state == SME_CONNECTED) { /* inform roam event to cfg80211 */ - cfg80211_roamed(vif->ndev, chan, bssid, - assoc_req_ie, assoc_req_len, - assoc_resp_ie, assoc_resp_len, GFP_KERNEL); + cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len, + assoc_resp_ie, assoc_resp_len, GFP_KERNEL); } } @@ -828,13 +854,13 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, if (vif->sme_state == SME_CONNECTING) { cfg80211_connect_result(vif->ndev, - bssid, NULL, 0, - NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); + bssid, NULL, 0, + NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); } else if (vif->sme_state == SME_CONNECTED) { cfg80211_disconnected(vif->ndev, reason, - NULL, 0, GFP_KERNEL); + NULL, 0, GFP_KERNEL); } vif->sme_state = SME_DISCONNECTED; @@ -880,19 +906,14 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, request->ssids[i].ssid); } - /* - * FIXME: we should clear the IE in fw if it's not set so just - * remove the check altogether - */ - if (request->ie) { - ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_PROBE_REQ, - request->ie, request->ie_len); - if (ret) { - ath6kl_err("failed to set Probe Request appie for " - "scan"); - return ret; - } + /* this also clears IE in fw if it's not set */ + ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, + WMI_FRAME_PROBE_REQ, + request->ie, request->ie_len); + if (ret) { + ath6kl_err("failed to set Probe Request appie for " + "scan"); + return ret; } /* @@ -921,7 +942,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, force_fg_scan = 1; if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, - ar->fw_capabilities)) { + ar->fw_capabilities)) { /* * If capable of doing P2P mgmt operations using * station interface, send additional information like @@ -930,14 +951,17 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, */ ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN, force_fg_scan, - false, 0, 0, n_channels, - channels, request->no_cck, + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels, + request->no_cck, request->rates); } else { ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN, force_fg_scan, - false, 0, 0, n_channels, - channels); + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels); } if (ret) ath6kl_err("wmi_startscan_cmd failed\n"); @@ -984,6 +1008,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, struct ath6kl *ar = ath6kl_priv(ndev); struct ath6kl_vif *vif = netdev_priv(ndev); struct ath6kl_key *key = NULL; + int seq_len; u8 key_usage; u8 key_type; @@ -997,7 +1022,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, params->key); } - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1012,23 +1037,21 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, else key_usage = GROUP_USAGE; - if (params) { - int seq_len = params->seq_len; - if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && - seq_len > ATH6KL_KEY_SEQ_LEN) { - /* Only first half of the WPI PN is configured */ - seq_len = ATH6KL_KEY_SEQ_LEN; - } - if (params->key_len > WLAN_MAX_KEY_LEN || - seq_len > sizeof(key->seq)) - return -EINVAL; - - key->key_len = params->key_len; - memcpy(key->key, params->key, key->key_len); - key->seq_len = seq_len; - memcpy(key->seq, params->seq, key->seq_len); - key->cipher = params->cipher; + seq_len = params->seq_len; + if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && + seq_len > ATH6KL_KEY_SEQ_LEN) { + /* Only first half of the WPI PN is configured */ + seq_len = ATH6KL_KEY_SEQ_LEN; } + if (params->key_len > WLAN_MAX_KEY_LEN || + seq_len > sizeof(key->seq)) + return -EINVAL; + + key->key_len = params->key_len; + memcpy(key->key, params->key, key->key_len); + key->seq_len = seq_len; + memcpy(key->seq, params->seq, key->seq_len); + key->cipher = params->cipher; switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: @@ -1051,9 +1074,9 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, return -ENOTSUPP; } - if (((vif->auth_mode == WPA_PSK_AUTH) - || (vif->auth_mode == WPA2_PSK_AUTH)) - && (key_usage & GROUP_USAGE)) + if (((vif->auth_mode == WPA_PSK_AUTH) || + (vif->auth_mode == WPA2_PSK_AUTH)) && + (key_usage & GROUP_USAGE)) del_timer(&vif->disconnect_timer); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, @@ -1063,7 +1086,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, if (vif->nw_type == AP_NETWORK && !pairwise && (key_type == TKIP_CRYPT || key_type == AES_CRYPT || - key_type == WAPI_CRYPT) && params) { + key_type == WAPI_CRYPT)) { ar->ap_mode_bkey.valid = true; ar->ap_mode_bkey.key_index = key_index; ar->ap_mode_bkey.key_type = key_type; @@ -1115,7 +1138,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1148,7 +1171,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1184,7 +1207,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1268,7 +1291,6 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, { struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); struct ath6kl_vif *vif; - u8 ath6kl_dbm; int dbm = MBM_TO_DBM(mbm); ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__, @@ -1285,7 +1307,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, case NL80211_TX_POWER_AUTOMATIC: return 0; case NL80211_TX_POWER_LIMITED: - ar->tx_pwr = ath6kl_dbm = dbm; + ar->tx_pwr = dbm; break; default: ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n", @@ -1293,7 +1315,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, return -EOPNOTSUPP; } - ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm); + ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm); return 0; } @@ -1354,7 +1376,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, } if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx, - mode.pwr_mode) != 0) { + mode.pwr_mode) != 0) { ath6kl_err("wmi_powermode_cmd failed\n"); return -EIO; } @@ -1403,7 +1425,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); - ath6kl_deinit_if_data(vif); + ath6kl_cfg80211_vif_cleanup(vif); return 0; } @@ -1728,29 +1750,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return 0; } -static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif, + struct cfg80211_wowlan *wow, u32 *filter) { - struct ath6kl_vif *vif; - int ret, pos, left; - u32 filter = 0; - u16 i; + int ret, pos; u8 mask[WOW_MASK_SIZE]; + u16 i; - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - if (!ath6kl_cfg80211_ready(vif)) - return -EIO; - - if (!test_bit(CONNECTED, &vif->flags)) - return -EINVAL; - - /* Clear existing WOW patterns */ - for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) - ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, - WOW_LIST_ID, i); - /* Configure new WOW patterns */ + /* Configure the patterns that we received from the user. */ for (i = 0; i < wow->n_patterns; i++) { /* @@ -1773,29 +1780,249 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) * matched from the first byte of received pkt in the firmware. */ ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, - vif->fw_vif_idx, WOW_LIST_ID, - wow->patterns[i].pattern_len, - 0 /* pattern offset */, - wow->patterns[i].pattern, mask); + vif->fw_vif_idx, WOW_LIST_ID, + wow->patterns[i].pattern_len, + 0 /* pattern offset */, + wow->patterns[i].pattern, mask); if (ret) return ret; } if (wow->disconnect) - filter |= WOW_FILTER_OPTION_NWK_DISASSOC; + *filter |= WOW_FILTER_OPTION_NWK_DISASSOC; if (wow->magic_pkt) - filter |= WOW_FILTER_OPTION_MAGIC_PACKET; + *filter |= WOW_FILTER_OPTION_MAGIC_PACKET; if (wow->gtk_rekey_failure) - filter |= WOW_FILTER_OPTION_GTK_ERROR; + *filter |= WOW_FILTER_OPTION_GTK_ERROR; if (wow->eap_identity_req) - filter |= WOW_FILTER_OPTION_EAP_REQ; + *filter |= WOW_FILTER_OPTION_EAP_REQ; if (wow->four_way_handshake) - filter |= WOW_FILTER_OPTION_8021X_4WAYHS; + *filter |= WOW_FILTER_OPTION_8021X_4WAYHS; + + return 0; +} + +static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif) +{ + static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08 }; + static const u8 unicst_mask[] = { 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f }; + u8 unicst_offset = 0; + static const u8 arp_pattern[] = { 0x08, 0x06 }; + static const u8 arp_mask[] = { 0xff, 0xff }; + u8 arp_offset = 20; + static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 }; + static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u8 discvr_offset = 38; + static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ }; + static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ }; + u8 dhcp_offset = 0; + int ret; + + /* Setup unicast IP, EAPOL-like and ARP pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(unicst_pattern), unicst_offset, + unicst_pattern, unicst_mask); + if (ret) { + ath6kl_err("failed to add WOW unicast IP pattern\n"); + return ret; + } + + /* Setup all ARP pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(arp_pattern), arp_offset, + arp_pattern, arp_mask); + if (ret) { + ath6kl_err("failed to add WOW ARP pattern\n"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(discvr_pattern), discvr_offset, + discvr_pattern, discvr_mask); + if (ret) { + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n"); + return ret; + } + + /* Setup all DHCP broadcast pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(dhcp_pattern), dhcp_offset, + dhcp_pattern, dhcp_mask); + if (ret) { + ath6kl_err("failed to add WOW DHCP broadcast pattern\n"); + return ret; + } + + return 0; +} + +static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif) +{ + struct net_device *ndev = vif->ndev; + static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 }; + static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u8 discvr_offset = 38; + u8 mac_mask[ETH_ALEN]; + int ret; + + /* Setup unicast pkt pattern */ + memset(mac_mask, 0xff, ETH_ALEN); + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + ETH_ALEN, 0, ndev->dev_addr, + mac_mask); + if (ret) { + ath6kl_err("failed to add WOW unicast pattern\n"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + if ((ndev->flags & IFF_ALLMULTI) || + (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) { + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(discvr_pattern), discvr_offset, + discvr_pattern, discvr_mask); + if (ret) { + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR " + "pattern\n"); + return ret; + } + } + return 0; +} + +static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +{ + struct in_device *in_dev; + struct in_ifaddr *ifa; + struct ath6kl_vif *vif; + int ret, left; + u32 filter = 0; + u16 i, bmiss_time; + u8 index = 0; + __be32 ips[MAX_IP_ADDRS]; + + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + if (!ath6kl_cfg80211_ready(vif)) + return -EIO; + + if (!test_bit(CONNECTED, &vif->flags)) + return -ENOTCONN; + + if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) + return -EINVAL; + + /* Clear existing WOW patterns */ + for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) + ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, + WOW_LIST_ID, i); + + /* + * Skip the default WOW pattern configuration + * if the driver receives any WOW patterns from + * the user. + */ + if (wow) + ret = ath6kl_wow_usr(ar, vif, wow, &filter); + else if (vif->nw_type == AP_NETWORK) + ret = ath6kl_wow_ap(ar, vif); + else + ret = ath6kl_wow_sta(ar, vif); + + if (ret) + return ret; + + netif_stop_queue(vif->ndev); + + if (vif->nw_type != AP_NETWORK) { + ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_MAX_WOW_LISTEN_INTL, + 0); + if (ret) + return ret; + + /* Set listen interval x 15 times as bmiss time */ + bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15; + if (bmiss_time > ATH6KL_MAX_BMISS_TIME) + bmiss_time = ATH6KL_MAX_BMISS_TIME; + + ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx, + bmiss_time, 0); + if (ret) + return ret; + + ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, + 0xFFFF, 0, 0xFFFF, 0, 0, 0, + 0, 0, 0, 0); + if (ret) + return ret; + } + + ar->state = ATH6KL_STATE_SUSPENDING; + + /* Setup own IP addr for ARP agent. */ + in_dev = __in_dev_get_rtnl(vif->ndev); + if (!in_dev) + goto skip_arp; + + ifa = in_dev->ifa_list; + memset(&ips, 0, sizeof(ips)); + + /* Configure IP addr only if IP address count < MAX_IP_ADDRS */ + while (index < MAX_IP_ADDRS && ifa) { + ips[index] = ifa->ifa_local; + ifa = ifa->ifa_next; + index++; + } + + if (ifa) { + ath6kl_err("total IP addr count is exceeding fw limit\n"); + return -EINVAL; + } + + ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]); + if (ret) { + ath6kl_err("fail to setup ip for arp agent\n"); + return ret; + } + +skip_arp: ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_WOW_MODE_ENABLE, filter, @@ -1803,11 +2030,26 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) if (ret) return ret; + clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_HOST_MODE_ASLEEP); if (ret) return ret; + left = wait_event_interruptible_timeout(ar->event_wq, + test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags), + WMI_TIMEOUT); + if (left == 0) { + ath6kl_warn("timeout, didn't get host sleep cmd " + "processed event\n"); + ret = -ETIMEDOUT; + } else if (left < 0) { + ath6kl_warn("error while waiting for host sleep cmd " + "processed event %d\n", left); + ret = left; + } + if (ar->tx_pending[ar->ctrl_ep]) { left = wait_event_interruptible_timeout(ar->event_wq, ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); @@ -1832,15 +2074,46 @@ static int ath6kl_wow_resume(struct ath6kl *ar) if (!vif) return -EIO; + ar->state = ATH6KL_STATE_RESUMING; + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_HOST_MODE_AWAKE); - return ret; + if (ret) { + ath6kl_warn("Failed to configure host sleep mode for " + "wow resume: %d\n", ret); + ar->state = ATH6KL_STATE_WOW; + return ret; + } + + if (vif->nw_type != AP_NETWORK) { + ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); + if (ret) + return ret; + + ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + vif->listen_intvl_t, 0); + if (ret) + return ret; + + ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx, + vif->bmiss_time_t, 0); + if (ret) + return ret; + } + + ar->state = ATH6KL_STATE_ON; + + netif_wake_queue(vif->ndev); + + return 0; } int ath6kl_cfg80211_suspend(struct ath6kl *ar, enum ath6kl_cfg_suspend_mode mode, struct cfg80211_wowlan *wow) { + enum ath6kl_state prev_state; int ret; switch (mode) { @@ -1851,11 +2124,14 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, /* Flush all non control pkts in TX path */ ath6kl_tx_data_cleanup(ar); + prev_state = ar->state; + ret = ath6kl_wow_suspend(ar, wow); if (ret) { - ath6kl_err("wow suspend failed: %d\n", ret); + ar->state = prev_state; return ret; } + ar->state = ATH6KL_STATE_WOW; break; @@ -1911,6 +2187,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, return 0; } +EXPORT_SYMBOL(ath6kl_cfg80211_suspend); int ath6kl_cfg80211_resume(struct ath6kl *ar) { @@ -1926,7 +2203,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) return ret; } - ar->state = ATH6KL_STATE_ON; break; case ATH6KL_STATE_DEEPSLEEP: @@ -1962,6 +2238,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) return 0; } +EXPORT_SYMBOL(ath6kl_cfg80211_resume); #ifdef CONFIG_PM @@ -1999,6 +2276,9 @@ static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) */ void ath6kl_check_wow_status(struct ath6kl *ar) { + if (ar->state == ATH6KL_STATE_SUSPENDING) + return; + if (ar->state == ATH6KL_STATE_WOW) ath6kl_cfg80211_resume(ar); } @@ -2014,7 +2294,18 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl_vif *vif; + + /* + * 'dev' could be NULL if a channel change is required for the hardware + * device itself, instead of a particular VIF. + * + * FIXME: To be handled properly when monitor mode is supported. + */ + if (!dev) + return -EBUSY; + + vif = netdev_priv(dev); if (!ath6kl_cfg80211_ready(vif)) return -EIO; @@ -2069,19 +2360,51 @@ static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif, return ret; } -static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *info, bool add) +static int ath6kl_set_ies(struct ath6kl_vif *vif, + struct cfg80211_beacon_data *info) +{ + struct ath6kl *ar = vif->ar; + int res; + + /* this also clears IE in fw if it's not set */ + res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, + WMI_FRAME_BEACON, + info->beacon_ies, + info->beacon_ies_len); + if (res) + return res; + + /* this also clears IE in fw if it's not set */ + res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies, + info->proberesp_ies_len); + if (res) + return res; + + /* this also clears IE in fw if it's not set */ + res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, + WMI_FRAME_ASSOC_RESP, + info->assocresp_ies, + info->assocresp_ies_len); + if (res) + return res; + + return 0; +} + +static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_ap_settings *info) { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); struct ieee80211_mgmt *mgmt; + bool hidden = false; u8 *ies; int ies_len; struct wmi_connect_cmd p; int res; int i, ret; - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add); + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); if (!ath6kl_cfg80211_ready(vif)) return -EIO; @@ -2089,31 +2412,7 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, if (vif->next_mode != AP_NETWORK) return -EOPNOTSUPP; - if (info->beacon_ies) { - res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_BEACON, - info->beacon_ies, - info->beacon_ies_len); - if (res) - return res; - } - if (info->proberesp_ies) { - res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies, - info->proberesp_ies_len); - if (res) - return res; - } - if (info->assocresp_ies) { - res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, - WMI_FRAME_ASSOC_RESP, - info->assocresp_ies, - info->assocresp_ies_len); - if (res) - return res; - } - - if (!add) - return 0; + res = ath6kl_set_ies(vif, &info->beacon); ar->ap_mode_bkey.valid = false; @@ -2122,20 +2421,24 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, * info->dtim_period */ - if (info->head == NULL) + if (info->beacon.head == NULL) return -EINVAL; - mgmt = (struct ieee80211_mgmt *) info->head; + mgmt = (struct ieee80211_mgmt *) info->beacon.head; ies = mgmt->u.beacon.variable; - if (ies > info->head + info->head_len) + if (ies > info->beacon.head + info->beacon.head_len) return -EINVAL; - ies_len = info->head + info->head_len - ies; + ies_len = info->beacon.head + info->beacon.head_len - ies; if (info->ssid == NULL) return -EINVAL; memcpy(vif->ssid, info->ssid, info->ssid_len); vif->ssid_len = info->ssid_len; if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE) - return -EOPNOTSUPP; /* TODO */ + hidden = true; + + res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden); + if (res) + return res; ret = ath6kl_set_auth_type(vif, info->auth_type); if (ret) @@ -2214,6 +2517,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, p.dot11_auth_mode = vif->dot11_auth_mode; p.ch = cpu_to_le16(vif->next_chan); + /* Enable uAPSD support by default */ + res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); + if (res < 0) + return res; + if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { p.nw_subtype = SUBTYPE_P2PGO; } else { @@ -2231,19 +2539,21 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, return 0; } -static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *info) +static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_beacon_data *beacon) { - return ath6kl_ap_beacon(wiphy, dev, info, true); -} + struct ath6kl_vif *vif = netdev_priv(dev); -static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev, - struct beacon_parameters *info) -{ - return ath6kl_ap_beacon(wiphy, dev, info, false); + if (!ath6kl_cfg80211_ready(vif)) + return -EIO; + + if (vif->next_mode != AP_NETWORK) + return -EOPNOTSUPP; + + return ath6kl_set_ies(vif, beacon); } -static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev) +static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) { struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); @@ -2259,6 +2569,19 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev) return 0; } +static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, + u8 *mac) +{ + struct ath6kl *ar = ath6kl_priv(dev); + struct ath6kl_vif *vif = netdev_priv(dev); + const u8 *addr = mac ? mac : bcast_addr; + + return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, + addr, WLAN_REASON_PREV_AUTH_NOT_VALID); +} + static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_parameters *params) { @@ -2354,6 +2677,76 @@ static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif, return ret; } +static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif, + u32 id, + u32 freq, + u32 wait, + const u8 *buf, + size_t len, + bool *more_data, + bool no_cck) +{ + struct ieee80211_mgmt *mgmt; + struct ath6kl_sta *conn; + bool is_psq_empty = false; + struct ath6kl_mgmt_buff *mgmt_buf; + size_t mgmt_buf_size; + struct ath6kl *ar = vif->ar; + + mgmt = (struct ieee80211_mgmt *) buf; + if (is_multicast_ether_addr(mgmt->da)) + return false; + + conn = ath6kl_find_sta(vif, mgmt->da); + if (!conn) + return false; + + if (conn->sta_flags & STA_PS_SLEEP) { + if (!(conn->sta_flags & STA_PS_POLLED)) { + /* Queue the frames if the STA is sleeping */ + mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff); + mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL); + if (!mgmt_buf) + return false; + + INIT_LIST_HEAD(&mgmt_buf->list); + mgmt_buf->id = id; + mgmt_buf->freq = freq; + mgmt_buf->wait = wait; + mgmt_buf->len = len; + mgmt_buf->no_cck = no_cck; + memcpy(mgmt_buf->buf, buf, len); + spin_lock_bh(&conn->psq_lock); + is_psq_empty = skb_queue_empty(&conn->psq) && + (conn->mgmt_psq_len == 0); + list_add_tail(&mgmt_buf->list, &conn->mgmt_psq); + conn->mgmt_psq_len++; + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this + * STA. + */ + if (is_psq_empty) + ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, + conn->aid, 1); + return true; + } + + /* + * This tx is because of a PsPoll. + * Determine if MoreData bit has to be set. + */ + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0)) + *more_data = true; + spin_unlock_bh(&conn->psq_lock); + } + + return false; +} + static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, bool offchan, enum nl80211_channel_type channel_type, @@ -2365,6 +2758,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, struct ath6kl_vif *vif = netdev_priv(dev); u32 id; const struct ieee80211_mgmt *mgmt; + bool more_data, queued; mgmt = (const struct ieee80211_mgmt *) buf; if (buf + len >= mgmt->u.probe_resp.variable && @@ -2390,22 +2784,19 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, *cookie = id; - if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, - ar->fw_capabilities)) { - /* - * If capable of doing P2P mgmt operations using - * station interface, send additional information like - * supported rates to advertise and xmit rates for - * probe requests - */ - return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, - chan->center_freq, wait, - buf, len, no_cck); - } else { - return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id, - chan->center_freq, wait, - buf, len); + /* AP mode Power saving processing */ + if (vif->nw_type == AP_NETWORK) { + queued = ath6kl_mgmt_powersave_ap(vif, + id, chan->center_freq, + wait, buf, + len, &more_data, no_cck); + if (queued) + return 0; } + + return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, + chan->center_freq, wait, + buf, len, no_cck); } static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, @@ -2518,6 +2909,12 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) }, + [NL80211_IFTYPE_AP] = { + .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_RESP >> 4), + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, [NL80211_IFTYPE_P2P_CLIENT] = { .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_RESP >> 4), @@ -2559,9 +2956,10 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .resume = __ath6kl_cfg80211_resume, #endif .set_channel = ath6kl_set_channel, - .add_beacon = ath6kl_add_beacon, - .set_beacon = ath6kl_set_beacon, - .del_beacon = ath6kl_del_beacon, + .start_ap = ath6kl_start_ap, + .change_beacon = ath6kl_change_beacon, + .stop_ap = ath6kl_stop_ap, + .del_station = ath6kl_del_station, .change_station = ath6kl_change_station, .remain_on_channel = ath6kl_remain_on_channel, .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, @@ -2629,122 +3027,9 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ath6kl_cfg80211_stop(vif); } -struct ath6kl *ath6kl_core_alloc(struct device *dev) -{ - struct ath6kl *ar; - struct wiphy *wiphy; - u8 ctr; - - /* create a new wiphy for use with cfg80211 */ - wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); - - if (!wiphy) { - ath6kl_err("couldn't allocate wiphy device\n"); - return NULL; - } - - ar = wiphy_priv(wiphy); - ar->p2p = !!ath6kl_p2p; - ar->wiphy = wiphy; - ar->dev = dev; - - ar->vif_max = 1; - - ar->max_norm_iface = 1; - - spin_lock_init(&ar->lock); - spin_lock_init(&ar->mcastpsq_lock); - spin_lock_init(&ar->list_lock); - - init_waitqueue_head(&ar->event_wq); - sema_init(&ar->sem, 1); - - INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue); - INIT_LIST_HEAD(&ar->vif_list); - - clear_bit(WMI_ENABLED, &ar->flag); - clear_bit(SKIP_SCAN, &ar->flag); - clear_bit(DESTROY_IN_PROGRESS, &ar->flag); - - ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL; - ar->listen_intvl_b = 0; - ar->tx_pwr = 0; - - ar->intra_bss = 1; - ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; - - ar->state = ATH6KL_STATE_OFF; - - memset((u8 *)ar->sta_list, 0, - AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); - - /* Init the PS queues */ - for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { - spin_lock_init(&ar->sta_list[ctr].psq_lock); - skb_queue_head_init(&ar->sta_list[ctr].psq); - } - - skb_queue_head_init(&ar->mcastpsq); - - memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); - - return ar; -} - -int ath6kl_register_ieee80211_hw(struct ath6kl *ar) -{ - struct wiphy *wiphy = ar->wiphy; - int ret; - - wiphy->mgmt_stypes = ath6kl_mgmt_stypes; - - wiphy->max_remain_on_channel_duration = 5000; - - /* set device pointer for wiphy */ - set_wiphy_dev(wiphy, ar->dev); - - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - if (ar->p2p) { - wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT); - } - - /* max num of ssids that can be probed during scanning */ - wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; - wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ - wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - wiphy->cipher_suites = cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | - WIPHY_WOWLAN_DISCONNECT | - WIPHY_WOWLAN_GTK_REKEY_FAILURE | - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | - WIPHY_WOWLAN_EAP_IDENTITY_REQ | - WIPHY_WOWLAN_4WAY_HANDSHAKE; - wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; - wiphy->wowlan.pattern_min_len = 1; - wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; - - wiphy->max_sched_scan_ssids = 10; - - ret = wiphy_register(wiphy); - if (ret < 0) { - ath6kl_err("couldn't register wiphy device\n"); - return ret; - } - - return 0; -} - -static int ath6kl_init_if_data(struct ath6kl_vif *vif) +static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { - vif->aggr_cntxt = aggr_init(vif->ndev); + vif->aggr_cntxt = aggr_init(vif); if (!vif->aggr_cntxt) { ath6kl_err("failed to initialize aggr\n"); return -ENOMEM; @@ -2758,12 +3043,15 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif) set_bit(WMM_ENABLED, &vif->flags); spin_lock_init(&vif->if_lock); + INIT_LIST_HEAD(&vif->mc_filter); + return 0; } -void ath6kl_deinit_if_data(struct ath6kl_vif *vif) +void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; + struct ath6kl_mc_filter *mc_filter, *tmp; aggr_module_destroy(vif->aggr_cntxt); @@ -2772,6 +3060,11 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif) if (vif->nw_type == ADHOC_NETWORK) ar->ibss_if_active = false; + list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { + list_del(&mc_filter->list); + kfree(mc_filter); + } + unregister_netdevice(vif->ndev); ar->num_vif--; @@ -2797,7 +3090,10 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, vif->wdev.netdev = ndev; vif->wdev.iftype = type; vif->fw_vif_idx = fw_vif_idx; - vif->nw_type = vif->next_mode = nw_type; + vif->nw_type = nw_type; + vif->next_mode = nw_type; + vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; + vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); if (fw_vif_idx != 0) @@ -2808,8 +3104,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, ath6kl_init_control_info(vif); - /* TODO: Pass interface specific pointer instead of ar */ - if (ath6kl_init_if_data(vif)) + if (ath6kl_cfg80211_vif_init(vif)) goto err; if (register_netdevice(ndev)) @@ -2836,8 +3131,107 @@ err: return NULL; } -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) +int ath6kl_cfg80211_init(struct ath6kl *ar) +{ + struct wiphy *wiphy = ar->wiphy; + int ret; + + wiphy->mgmt_stypes = ath6kl_mgmt_stypes; + + wiphy->max_remain_on_channel_duration = 5000; + + /* set device pointer for wiphy */ + set_wiphy_dev(wiphy, ar->dev); + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + if (ar->p2p) { + wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT); + } + + /* max num of ssids that can be probed during scanning */ + wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; + wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ + wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; + wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->cipher_suites = cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + + wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | + WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_GTK_REKEY_FAILURE | + WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_EAP_IDENTITY_REQ | + WIPHY_WOWLAN_4WAY_HANDSHAKE; + wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; + wiphy->wowlan.pattern_min_len = 1; + wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; + + wiphy->max_sched_scan_ssids = 10; + + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | + WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; + + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + + ar->wiphy->probe_resp_offload = + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + + ret = wiphy_register(wiphy); + if (ret < 0) { + ath6kl_err("couldn't register wiphy device\n"); + return ret; + } + + ar->wiphy_registered = true; + + return 0; +} + +void ath6kl_cfg80211_cleanup(struct ath6kl *ar) { wiphy_unregister(ar->wiphy); + + ar->wiphy_registered = false; +} + +struct ath6kl *ath6kl_cfg80211_create(void) +{ + struct ath6kl *ar; + struct wiphy *wiphy; + + /* create a new wiphy for use with cfg80211 */ + wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); + + if (!wiphy) { + ath6kl_err("couldn't allocate wiphy device\n"); + return NULL; + } + + ar = wiphy_priv(wiphy); + ar->wiphy = wiphy; + + return ar; +} + +/* Note: ar variable must not be accessed after calling this! */ +void ath6kl_cfg80211_destroy(struct ath6kl *ar) +{ + int i; + + for (i = 0; i < AP_MAX_NUM_STA; i++) + kfree(ar->sta_list[i].aggr_conn); + wiphy_free(ar->wiphy); } + diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 81f20a57231..c5def436417 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -27,10 +28,6 @@ enum ath6kl_cfg_suspend_mode { struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); -int ath6kl_register_ieee80211_hw(struct ath6kl *ar); -struct ath6kl *ath6kl_core_alloc(struct device *dev); -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar); - void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -53,7 +50,15 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, int ath6kl_cfg80211_resume(struct ath6kl *ar); +void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif); + void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop_all(struct ath6kl *ar); +int ath6kl_cfg80211_init(struct ath6kl *ar); +void ath6kl_cfg80211_cleanup(struct ath6kl *ar); + +struct ath6kl *ath6kl_cfg80211_create(void); +void ath6kl_cfg80211_destroy(struct ath6kl *ar); + #endif /* ATH6KL_CFG80211_H */ diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index bfd6597763d..a60e78c0472 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -79,8 +80,5 @@ struct ath6kl; enum htc_credit_dist_reason; struct ath6kl_htc_credit_info; -struct ath6kl *ath6kl_core_alloc(struct device *sdev); -int ath6kl_core_init(struct ath6kl *ar); -void ath6kl_core_cleanup(struct ath6kl *ar); struct sk_buff *ath6kl_buf_alloc(int size); #endif /* COMMON_H */ diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c new file mode 100644 index 00000000000..45e641f3a41 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "core.h" + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/export.h> + +#include "debug.h" +#include "hif-ops.h" +#include "cfg80211.h" + +unsigned int debug_mask; +static unsigned int suspend_mode; +static unsigned int wow_mode; +static unsigned int uart_debug; +static unsigned int ath6kl_p2p; +static unsigned int testmode; + +module_param(debug_mask, uint, 0644); +module_param(suspend_mode, uint, 0644); +module_param(wow_mode, uint, 0644); +module_param(uart_debug, uint, 0644); +module_param(ath6kl_p2p, uint, 0644); +module_param(testmode, uint, 0644); + +int ath6kl_core_init(struct ath6kl *ar) +{ + struct ath6kl_bmi_target_info targ_info; + struct net_device *ndev; + int ret = 0, i; + + ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); + if (!ar->ath6kl_wq) + return -ENOMEM; + + ret = ath6kl_bmi_init(ar); + if (ret) + goto err_wq; + + /* + * Turn on power to get hardware (target) version and leave power + * on delibrately as we will boot the hardware anyway within few + * seconds. + */ + ret = ath6kl_hif_power_on(ar); + if (ret) + goto err_bmi_cleanup; + + ret = ath6kl_bmi_get_target_info(ar, &targ_info); + if (ret) + goto err_power_off; + + ar->version.target_ver = le32_to_cpu(targ_info.version); + ar->target_type = le32_to_cpu(targ_info.type); + ar->wiphy->hw_version = le32_to_cpu(targ_info.version); + + ret = ath6kl_init_hw_params(ar); + if (ret) + goto err_power_off; + + ar->htc_target = ath6kl_htc_create(ar); + + if (!ar->htc_target) { + ret = -ENOMEM; + goto err_power_off; + } + + ar->testmode = testmode; + + ret = ath6kl_init_fetch_firmwares(ar); + if (ret) + goto err_htc_cleanup; + + /* FIXME: we should free all firmwares in the error cases below */ + + /* Indicate that WMI is enabled (although not ready yet) */ + set_bit(WMI_ENABLED, &ar->flag); + ar->wmi = ath6kl_wmi_init(ar); + if (!ar->wmi) { + ath6kl_err("failed to initialize wmi\n"); + ret = -EIO; + goto err_htc_cleanup; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); + + /* setup access class priority mappings */ + ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ + ar->ac_stream_pri_map[WMM_AC_BE] = 1; + ar->ac_stream_pri_map[WMM_AC_VI] = 2; + ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ + + /* allocate some buffers that handle larger AMSDU frames */ + ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); + + ath6kl_cookie_init(ar); + + ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | + ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; + + if (suspend_mode && + suspend_mode >= WLAN_POWER_STATE_CUT_PWR && + suspend_mode <= WLAN_POWER_STATE_WOW) + ar->suspend_mode = suspend_mode; + else + ar->suspend_mode = 0; + + if (suspend_mode == WLAN_POWER_STATE_WOW && + (wow_mode == WLAN_POWER_STATE_CUT_PWR || + wow_mode == WLAN_POWER_STATE_DEEP_SLEEP)) + ar->wow_suspend_mode = wow_mode; + else + ar->wow_suspend_mode = 0; + + if (uart_debug) + ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; + + set_bit(FIRST_BOOT, &ar->flag); + + ath6kl_debug_init(ar); + + ret = ath6kl_init_hw_start(ar); + if (ret) { + ath6kl_err("Failed to start hardware: %d\n", ret); + goto err_rxbuf_cleanup; + } + + /* give our connected endpoints some buffers */ + ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); + ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); + + ret = ath6kl_cfg80211_init(ar); + if (ret) + goto err_rxbuf_cleanup; + + ret = ath6kl_debug_init_fs(ar); + if (ret) { + wiphy_unregister(ar->wiphy); + goto err_rxbuf_cleanup; + } + + for (i = 0; i < ar->vif_max; i++) + ar->avail_idx_map |= BIT(i); + + rtnl_lock(); + + /* Add an initial station interface */ + ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, + INFRA_NETWORK); + + rtnl_unlock(); + + if (!ndev) { + ath6kl_err("Failed to instantiate a network device\n"); + ret = -ENOMEM; + wiphy_unregister(ar->wiphy); + goto err_rxbuf_cleanup; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", + __func__, ndev->name, ndev, ar); + + return ret; + +err_rxbuf_cleanup: + ath6kl_debug_cleanup(ar); + ath6kl_htc_flush_rx_buf(ar->htc_target); + ath6kl_cleanup_amsdu_rxbufs(ar); + ath6kl_wmi_shutdown(ar->wmi); + clear_bit(WMI_ENABLED, &ar->flag); + ar->wmi = NULL; +err_htc_cleanup: + ath6kl_htc_cleanup(ar->htc_target); +err_power_off: + ath6kl_hif_power_off(ar); +err_bmi_cleanup: + ath6kl_bmi_cleanup(ar); +err_wq: + destroy_workqueue(ar->ath6kl_wq); + + return ret; +} +EXPORT_SYMBOL(ath6kl_core_init); + +struct ath6kl *ath6kl_core_create(struct device *dev) +{ + struct ath6kl *ar; + u8 ctr; + + ar = ath6kl_cfg80211_create(); + if (!ar) + return NULL; + + ar->p2p = !!ath6kl_p2p; + ar->dev = dev; + + ar->vif_max = 1; + + ar->max_norm_iface = 1; + + spin_lock_init(&ar->lock); + spin_lock_init(&ar->mcastpsq_lock); + spin_lock_init(&ar->list_lock); + + init_waitqueue_head(&ar->event_wq); + sema_init(&ar->sem, 1); + + INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue); + INIT_LIST_HEAD(&ar->vif_list); + + clear_bit(WMI_ENABLED, &ar->flag); + clear_bit(SKIP_SCAN, &ar->flag); + clear_bit(DESTROY_IN_PROGRESS, &ar->flag); + + ar->tx_pwr = 0; + ar->intra_bss = 1; + ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; + + ar->state = ATH6KL_STATE_OFF; + + memset((u8 *)ar->sta_list, 0, + AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); + + /* Init the PS queues */ + for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { + spin_lock_init(&ar->sta_list[ctr].psq_lock); + skb_queue_head_init(&ar->sta_list[ctr].psq); + skb_queue_head_init(&ar->sta_list[ctr].apsdq); + ar->sta_list[ctr].mgmt_psq_len = 0; + INIT_LIST_HEAD(&ar->sta_list[ctr].mgmt_psq); + ar->sta_list[ctr].aggr_conn = + kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + if (!ar->sta_list[ctr].aggr_conn) { + ath6kl_err("Failed to allocate memory for sta aggregation information\n"); + ath6kl_core_destroy(ar); + return NULL; + } + } + + skb_queue_head_init(&ar->mcastpsq); + + memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); + + return ar; +} +EXPORT_SYMBOL(ath6kl_core_create); + +void ath6kl_core_cleanup(struct ath6kl *ar) +{ + ath6kl_hif_power_off(ar); + + destroy_workqueue(ar->ath6kl_wq); + + if (ar->htc_target) + ath6kl_htc_cleanup(ar->htc_target); + + ath6kl_cookie_cleanup(ar); + + ath6kl_cleanup_amsdu_rxbufs(ar); + + ath6kl_bmi_cleanup(ar); + + ath6kl_debug_cleanup(ar); + + kfree(ar->fw_board); + kfree(ar->fw_otp); + kfree(ar->fw); + kfree(ar->fw_patch); + kfree(ar->fw_testscript); + + ath6kl_cfg80211_cleanup(ar); +} +EXPORT_SYMBOL(ath6kl_core_cleanup); + +void ath6kl_core_destroy(struct ath6kl *ar) +{ + ath6kl_cfg80211_destroy(ar); +} +EXPORT_SYMBOL(ath6kl_core_destroy); + +MODULE_AUTHOR("Qualcomm Atheros"); +MODULE_DESCRIPTION("Core module for AR600x SDIO and USB devices."); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c863a28f2e0..f1dd8906be4 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -44,6 +45,10 @@ #define ATH6KL_MAX_ENDPOINTS 4 #define MAX_NODE_NUM 15 +#define ATH6KL_APSD_ALL_FRAME 0xFFFF +#define ATH6KL_APSD_NUM_OF_AC 0x4 +#define ATH6KL_APSD_FRAME_MASK 0xF + /* Extra bytes for htc header alignment */ #define ATH6KL_HTC_ALIGN_BYTES 3 @@ -55,8 +60,9 @@ #define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) #define DISCON_TIMER_INTVAL 10000 /* in msec */ -#define A_DEFAULT_LISTEN_INTERVAL 100 -#define A_MAX_WOW_LISTEN_INTERVAL 1000 + +/* Channel dwell time in fg scan */ +#define ATH6KL_FG_SCAN_INTERVAL 50 /* in ms */ /* includes also the null byte */ #define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL" @@ -97,45 +103,49 @@ struct ath6kl_fw_ie { u8 data[0]; }; +#define ATH6KL_FW_API2_FILE "fw-2.bin" +#define ATH6KL_FW_API3_FILE "fw-3.bin" + /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba /* AR6003 2.0 definitions */ #define AR6003_HW_2_0_VERSION 0x30000384 #define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910 -#define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" -#define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" -#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" -#define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" -#define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin" +#define AR6003_HW_2_0_FW_DIR "ath6k/AR6003/hw2.0" +#define AR6003_HW_2_0_OTP_FILE "otp.bin.z77" +#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" +#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6003/hw2.0/bdata.SD31.bin" /* AR6003 3.0 definitions */ #define AR6003_HW_2_1_1_VERSION 0x30000582 -#define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" -#define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" -#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \ - "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" -#define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" -#define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin" +#define AR6003_HW_2_1_1_FW_DIR "ath6k/AR6003/hw2.1.1" +#define AR6003_HW_2_1_1_OTP_FILE "otp.bin" +#define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin" +#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" +#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" +#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" /* AR6004 1.0 definitions */ #define AR6004_HW_1_0_VERSION 0x30000623 -#define AR6004_HW_1_0_FIRMWARE_2_FILE "ath6k/AR6004/hw1.0/fw-2.bin" -#define AR6004_HW_1_0_FIRMWARE_FILE "ath6k/AR6004/hw1.0/fw.ram.bin" +#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" +#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" #define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6004/hw1.0/bdata.DB132.bin" /* AR6004 1.1 definitions */ #define AR6004_HW_1_1_VERSION 0x30000001 -#define AR6004_HW_1_1_FIRMWARE_2_FILE "ath6k/AR6004/hw1.1/fw-2.bin" -#define AR6004_HW_1_1_FIRMWARE_FILE "ath6k/AR6004/hw1.1/fw.ram.bin" +#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" +#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" #define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6004/hw1.1/bdata.DB132.bin" @@ -144,6 +154,8 @@ struct ath6kl_fw_ie { #define STA_PS_AWAKE BIT(0) #define STA_PS_SLEEP BIT(1) #define STA_PS_POLLED BIT(2) +#define STA_PS_APSD_TRIGGER BIT(3) +#define STA_PS_APSD_EOSP BIT(4) /* HTC TX packet tagging definitions */ #define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED @@ -173,6 +185,11 @@ struct ath6kl_fw_ie { #define MBOX_YIELD_LIMIT 99 +#define ATH6KL_DEFAULT_LISTEN_INTVAL 100 /* in TUs */ +#define ATH6KL_DEFAULT_BMISS_TIME 1500 +#define ATH6KL_MAX_WOW_LISTEN_INTL 300 /* in TUs */ +#define ATH6KL_MAX_BMISS_TIME 5000 + /* configuration lags */ /* * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in @@ -186,7 +203,7 @@ struct ath6kl_fw_ie { #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1) #define ATH6KL_CONF_ENABLE_11N BIT(2) #define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) -#define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) +#define ATH6KL_CONF_UART_DEBUG BIT(4) enum wlan_low_pwr_state { WLAN_POWER_STATE_ON, @@ -216,6 +233,12 @@ struct rxtid { u32 hold_q_sz; struct skb_hold_q *hold_q; struct sk_buff_head q; + + /* + * FIXME: No clue what this should protect. Apparently it should + * protect some of the fields above but they are also accessed + * without taking the lock. + */ spinlock_t lock; }; @@ -231,14 +254,19 @@ struct rxtid_stats { u32 num_bar; }; -struct aggr_info { +struct aggr_info_conn { u8 aggr_sz; u8 timer_scheduled; struct timer_list timer; struct net_device *dev; struct rxtid rx_tid[NUM_OF_TIDS]; - struct sk_buff_head free_q; struct rxtid_stats stat[NUM_OF_TIDS]; + struct aggr_info *aggr_info; +}; + +struct aggr_info { + struct aggr_info_conn *aggr_conn; + struct sk_buff_head rx_amsdu_freeq; }; struct ath6kl_wep_key { @@ -270,6 +298,16 @@ struct ath6kl_cookie { struct ath6kl_cookie *arc_list_next; }; +struct ath6kl_mgmt_buff { + struct list_head list; + u32 freq; + u32 wait; + u32 id; + bool no_cck; + size_t len; + u8 buf[0]; +}; + struct ath6kl_sta { u16 sta_flags; u8 mac[ETH_ALEN]; @@ -279,7 +317,15 @@ struct ath6kl_sta { u8 auth; u8 wpa_ie[ATH6KL_MAX_IE]; struct sk_buff_head psq; + + /* protects psq, mgmt_psq, apsdq, and mgmt_psq_len fields */ spinlock_t psq_lock; + + struct list_head mgmt_psq; + size_t mgmt_psq_len; + u8 apsd_info; + struct sk_buff_head apsdq; + struct aggr_info_conn *aggr_conn; }; struct ath6kl_version { @@ -408,6 +454,13 @@ enum ath6kl_hif_type { ATH6KL_HIF_TYPE_USB, }; +/* Max number of filters that hw supports */ +#define ATH6K_MAX_MC_FILTERS_PER_LIST 7 +struct ath6kl_mc_filter { + struct list_head list; + char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; +}; + /* * Driver's maximum limit, note that some firmwares support only one vif * and the runtime (current) limit must be checked from ar->vif_max. @@ -426,6 +479,7 @@ enum ath6kl_vif_state { DTIM_PERIOD_AVAIL, WLAN_ENABLED, STATS_UPDATE_PEND, + HOST_SLEEP_MODE_CMD_PROCESSED, }; struct ath6kl_vif { @@ -468,9 +522,13 @@ struct ath6kl_vif { bool probe_req_report; u16 next_chan; u16 assoc_bss_beacon_int; + u16 listen_intvl_t; + u16 bmiss_time_t; u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; + + struct list_head mc_filter; }; #define WOW_LIST_ID 0 @@ -493,6 +551,8 @@ enum ath6kl_dev_state { enum ath6kl_state { ATH6KL_STATE_OFF, ATH6KL_STATE_ON, + ATH6KL_STATE_SUSPENDING, + ATH6KL_STATE_RESUMING, ATH6KL_STATE_DEEPSLEEP, ATH6KL_STATE_CUTPOWER, ATH6KL_STATE_WOW, @@ -504,6 +564,7 @@ struct ath6kl { struct wiphy *wiphy; enum ath6kl_state state; + unsigned int testmode; struct ath6kl_bmi bmi; const struct ath6kl_hif_ops *hif_ops; @@ -520,10 +581,14 @@ struct ath6kl { unsigned int vif_max; u8 max_norm_iface; u8 avail_idx_map; + + /* + * Protects at least amsdu_rx_buffer_queue, ath6kl_alloc_cookie() + * calls, tx_pending and total_tx_data_pend. + */ spinlock_t lock; + struct semaphore sem; - u16 listen_intvl_b; - u16 listen_intvl_t; u8 lrssi_roam_threshold; struct ath6kl_version version; u32 target_type; @@ -549,7 +614,13 @@ struct ath6kl { u8 sta_list_index; struct ath6kl_req_key ap_mode_bkey; struct sk_buff_head mcastpsq; + + /* + * FIXME: protects access to mcastpsq but is actually useless as + * all skbe_queue_*() functions provide serialisation themselves + */ spinlock_t mcastpsq_lock; + u8 intra_bss; struct wmi_ap_mode_stat ap_stats; u8 ap_country_code[3]; @@ -574,17 +645,25 @@ struct ath6kl { u32 board_addr; u32 refclk_hz; u32 uarttx_pin; + u32 testscript_addr; + + struct ath6kl_hw_fw { + const char *dir; + const char *otp; + const char *fw; + const char *tcmd; + const char *patch; + const char *utf; + const char *testscript; + } fw; - const char *fw_otp; - const char *fw; - const char *fw_tcmd; - const char *fw_patch; - const char *fw_api2; const char *fw_board; const char *fw_default_board; } hw; u16 conf_flags; + u16 suspend_mode; + u16 wow_suspend_mode; wait_queue_head_t event_wq; struct ath6kl_mbox_info mbox_info; @@ -603,6 +682,10 @@ struct ath6kl { u8 *fw_patch; size_t fw_patch_len; + u8 *fw_testscript; + size_t fw_testscript_len; + + unsigned int fw_api; unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN]; struct workqueue_struct *ath6kl_wq; @@ -611,12 +694,16 @@ struct ath6kl { bool p2p; + bool wiphy_registered; + #ifdef CONFIG_ATH6KL_DEBUG struct { - struct circ_buf fwlog_buf; - spinlock_t fwlog_lock; - void *fwlog_tmp; + struct sk_buff_head fwlog_queue; + struct completion fwlog_completion; + bool fwlog_open; + u32 fwlog_mask; + unsigned int dbgfs_diag_reg; u32 diag_reg_addr_wr; u32 diag_reg_val_wr; @@ -676,7 +763,9 @@ struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar); void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); -struct aggr_info *aggr_init(struct net_device *dev); +struct aggr_info *aggr_init(struct ath6kl_vif *vif); +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, + struct aggr_info_conn *aggr_conn); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); @@ -684,12 +773,12 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target, enum htc_endpoint_id endpoint, int len); void aggr_module_destroy(struct aggr_info *aggr_info); -void aggr_reset_state(struct aggr_info *aggr_info); +void aggr_reset_state(struct aggr_info_conn *aggr_conn); -struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); +struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr); struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); -void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver); +void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver); int ath6kl_control_tx(void *devt, struct sk_buff *skb, enum htc_endpoint_id eid); void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -700,7 +789,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel); void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, - u8 assoc_req_len, u8 *assoc_info); + u8 assoc_req_len, u8 *assoc_info, u8 apsd_info); void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 prot_reason_status); @@ -723,12 +812,18 @@ void ath6kl_wakeup_event(void *dev); void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, bool wait_fot_compltn, bool cold_reset); void ath6kl_init_control_info(struct ath6kl_vif *vif); -void ath6kl_deinit_if_data(struct ath6kl_vif *vif); -void ath6kl_core_free(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); int ath6kl_init_hw_start(struct ath6kl *ar); int ath6kl_init_hw_stop(struct ath6kl *ar); +int ath6kl_init_fetch_firmwares(struct ath6kl *ar); +int ath6kl_init_hw_params(struct ath6kl *ar); + void ath6kl_check_wow_status(struct ath6kl *ar); +struct ath6kl *ath6kl_core_create(struct device *dev); +int ath6kl_core_init(struct ath6kl *ar); +void ath6kl_core_cleanup(struct ath6kl *ar); +void ath6kl_core_destroy(struct ath6kl *ar); + #endif /* CORE_H */ diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index eb808b46f94..552adb3f80d 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -16,7 +17,7 @@ #include "core.h" -#include <linux/circ_buf.h> +#include <linux/skbuff.h> #include <linux/fs.h> #include <linux/vmalloc.h> #include <linux/export.h> @@ -32,9 +33,8 @@ struct ath6kl_fwlog_slot { u8 payload[0]; }; -#define ATH6KL_FWLOG_SIZE 32768 -#define ATH6KL_FWLOG_SLOT_SIZE (sizeof(struct ath6kl_fwlog_slot) + \ - ATH6KL_FWLOG_PAYLOAD_SIZE) +#define ATH6KL_FWLOG_MAX_ENTRIES 20 + #define ATH6KL_FWLOG_VALID_MASK 0x1ffff int ath6kl_printk(const char *level, const char *fmt, ...) @@ -54,9 +54,42 @@ int ath6kl_printk(const char *level, const char *fmt, ...) return rtn; } +EXPORT_SYMBOL(ath6kl_printk); #ifdef CONFIG_ATH6KL_DEBUG +void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + if (!(debug_mask & mask)) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + ath6kl_printk(KERN_DEBUG, "%pV", &vaf); + + va_end(args); +} +EXPORT_SYMBOL(ath6kl_dbg); + +void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, + const char *msg, const char *prefix, + const void *buf, size_t len) +{ + if (debug_mask & mask) { + if (msg) + ath6kl_dbg(mask, "%s\n", msg); + + print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); + } +} +EXPORT_SYMBOL(ath6kl_dbg_dump); + #define REG_OUTPUT_LEN_PER_LINE 25 #define REGTYPE_STR_LEN 100 @@ -82,63 +115,63 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, struct ath6kl_irq_enable_reg *irq_enable_reg) { - ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n")); + ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n")); if (irq_proc_reg != NULL) { - ath6kl_dbg(ATH6KL_DBG_ANY, - "Host Int status: 0x%x\n", - irq_proc_reg->host_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, + "Host Int status: 0x%x\n", + irq_proc_reg->host_int_status); + ath6kl_dbg(ATH6KL_DBG_IRQ, "CPU Int status: 0x%x\n", - irq_proc_reg->cpu_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + irq_proc_reg->cpu_int_status); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Error Int status: 0x%x\n", - irq_proc_reg->error_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + irq_proc_reg->error_int_status); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status: 0x%x\n", - irq_proc_reg->counter_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + irq_proc_reg->counter_int_status); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Mbox Frame: 0x%x\n", - irq_proc_reg->mbox_frame); - ath6kl_dbg(ATH6KL_DBG_ANY, + irq_proc_reg->mbox_frame); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead Valid: 0x%x\n", - irq_proc_reg->rx_lkahd_valid); - ath6kl_dbg(ATH6KL_DBG_ANY, + irq_proc_reg->rx_lkahd_valid); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 0: 0x%x\n", - irq_proc_reg->rx_lkahd[0]); - ath6kl_dbg(ATH6KL_DBG_ANY, + irq_proc_reg->rx_lkahd[0]); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 1: 0x%x\n", - irq_proc_reg->rx_lkahd[1]); + irq_proc_reg->rx_lkahd[1]); if (dev->ar->mbox_info.gmbox_addr != 0) { /* * If the target supports GMBOX hardware, dump some * additional state. */ - ath6kl_dbg(ATH6KL_DBG_ANY, - "GMBOX Host Int status 2: 0x%x\n", - irq_proc_reg->host_int_status2); - ath6kl_dbg(ATH6KL_DBG_ANY, - "GMBOX RX Avail: 0x%x\n", - irq_proc_reg->gmbox_rx_avail); - ath6kl_dbg(ATH6KL_DBG_ANY, - "GMBOX lookahead alias 0: 0x%x\n", - irq_proc_reg->rx_gmbox_lkahd_alias[0]); - ath6kl_dbg(ATH6KL_DBG_ANY, - "GMBOX lookahead alias 1: 0x%x\n", - irq_proc_reg->rx_gmbox_lkahd_alias[1]); + ath6kl_dbg(ATH6KL_DBG_IRQ, + "GMBOX Host Int status 2: 0x%x\n", + irq_proc_reg->host_int_status2); + ath6kl_dbg(ATH6KL_DBG_IRQ, + "GMBOX RX Avail: 0x%x\n", + irq_proc_reg->gmbox_rx_avail); + ath6kl_dbg(ATH6KL_DBG_IRQ, + "GMBOX lookahead alias 0: 0x%x\n", + irq_proc_reg->rx_gmbox_lkahd_alias[0]); + ath6kl_dbg(ATH6KL_DBG_IRQ, + "GMBOX lookahead alias 1: 0x%x\n", + irq_proc_reg->rx_gmbox_lkahd_alias[1]); } } if (irq_enable_reg != NULL) { - ath6kl_dbg(ATH6KL_DBG_ANY, - "Int status Enable: 0x%x\n", - irq_enable_reg->int_status_en); - ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n", - irq_enable_reg->cntr_int_status_en); + ath6kl_dbg(ATH6KL_DBG_IRQ, + "Int status Enable: 0x%x\n", + irq_enable_reg->int_status_en); + ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", + irq_enable_reg->cntr_int_status_en); } - ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n"); + ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); } static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) @@ -175,9 +208,6 @@ void dump_cred_dist_stats(struct htc_target *target) { struct htc_endpoint_credit_dist *ep_list; - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT)) - return; - list_for_each_entry(ep_list, &target->cred_dist_list, list) dump_cred_dist(ep_list); @@ -238,105 +268,103 @@ static const struct file_operations fops_war_stats = { .llseek = default_llseek, }; -static void ath6kl_debug_fwlog_add(struct ath6kl *ar, const void *buf, - size_t buf_len) +void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) { - struct circ_buf *fwlog = &ar->debug.fwlog_buf; - size_t space; - int i; + struct ath6kl_fwlog_slot *slot; + struct sk_buff *skb; + size_t slot_len; - /* entries must all be equal size */ - if (WARN_ON(buf_len != ATH6KL_FWLOG_SLOT_SIZE)) + if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) return; - space = CIRC_SPACE(fwlog->head, fwlog->tail, ATH6KL_FWLOG_SIZE); - if (space < buf_len) - /* discard oldest slot */ - fwlog->tail = (fwlog->tail + ATH6KL_FWLOG_SLOT_SIZE) & - (ATH6KL_FWLOG_SIZE - 1); + slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE; - for (i = 0; i < buf_len; i += space) { - space = CIRC_SPACE_TO_END(fwlog->head, fwlog->tail, - ATH6KL_FWLOG_SIZE); + skb = alloc_skb(slot_len, GFP_KERNEL); + if (!skb) + return; - if ((size_t) space > buf_len - i) - space = buf_len - i; + slot = (struct ath6kl_fwlog_slot *) skb_put(skb, slot_len); + slot->timestamp = cpu_to_le32(jiffies); + slot->length = cpu_to_le32(len); + memcpy(slot->payload, buf, len); - memcpy(&fwlog->buf[fwlog->head], buf, space); - fwlog->head = (fwlog->head + space) & (ATH6KL_FWLOG_SIZE - 1); - } + /* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */ + memset(slot->payload + len, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - len); -} + spin_lock(&ar->debug.fwlog_queue.lock); -void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len) -{ - struct ath6kl_fwlog_slot *slot = ar->debug.fwlog_tmp; - size_t slot_len; + __skb_queue_tail(&ar->debug.fwlog_queue, skb); + complete(&ar->debug.fwlog_completion); - if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE)) - return; + /* drop oldest entries */ + while (skb_queue_len(&ar->debug.fwlog_queue) > + ATH6KL_FWLOG_MAX_ENTRIES) { + skb = __skb_dequeue(&ar->debug.fwlog_queue); + kfree_skb(skb); + } - spin_lock_bh(&ar->debug.fwlog_lock); + spin_unlock(&ar->debug.fwlog_queue.lock); - slot->timestamp = cpu_to_le32(jiffies); - slot->length = cpu_to_le32(len); - memcpy(slot->payload, buf, len); + return; +} - slot_len = sizeof(*slot) + len; +static int ath6kl_fwlog_open(struct inode *inode, struct file *file) +{ + struct ath6kl *ar = inode->i_private; - if (slot_len < ATH6KL_FWLOG_SLOT_SIZE) - memset(slot->payload + len, 0, - ATH6KL_FWLOG_SLOT_SIZE - slot_len); + if (ar->debug.fwlog_open) + return -EBUSY; - ath6kl_debug_fwlog_add(ar, slot, ATH6KL_FWLOG_SLOT_SIZE); + ar->debug.fwlog_open = true; - spin_unlock_bh(&ar->debug.fwlog_lock); + file->private_data = inode->i_private; + return 0; } -static bool ath6kl_debug_fwlog_empty(struct ath6kl *ar) +static int ath6kl_fwlog_release(struct inode *inode, struct file *file) { - return CIRC_CNT(ar->debug.fwlog_buf.head, - ar->debug.fwlog_buf.tail, - ATH6KL_FWLOG_SLOT_SIZE) == 0; + struct ath6kl *ar = inode->i_private; + + ar->debug.fwlog_open = false; + + return 0; } static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - struct circ_buf *fwlog = &ar->debug.fwlog_buf; - size_t len = 0, buf_len = count; + struct sk_buff *skb; ssize_t ret_cnt; + size_t len = 0; char *buf; - int ccnt; - buf = vmalloc(buf_len); + buf = vmalloc(count); if (!buf) return -ENOMEM; /* read undelivered logs from firmware */ ath6kl_read_fwlogs(ar); - spin_lock_bh(&ar->debug.fwlog_lock); + spin_lock(&ar->debug.fwlog_queue.lock); - while (len < buf_len && !ath6kl_debug_fwlog_empty(ar)) { - ccnt = CIRC_CNT_TO_END(fwlog->head, fwlog->tail, - ATH6KL_FWLOG_SIZE); + while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&ar->debug.fwlog_queue, skb); + break; + } - if ((size_t) ccnt > buf_len - len) - ccnt = buf_len - len; - memcpy(buf + len, &fwlog->buf[fwlog->tail], ccnt); - len += ccnt; + memcpy(buf + len, skb->data, skb->len); + len += skb->len; - fwlog->tail = (fwlog->tail + ccnt) & - (ATH6KL_FWLOG_SIZE - 1); + kfree_skb(skb); } - spin_unlock_bh(&ar->debug.fwlog_lock); + spin_unlock(&ar->debug.fwlog_queue.lock); - if (WARN_ON(len > buf_len)) - len = buf_len; + /* FIXME: what to do if len == 0? */ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); @@ -346,12 +374,87 @@ static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf, } static const struct file_operations fops_fwlog = { - .open = ath6kl_debugfs_open, + .open = ath6kl_fwlog_open, + .release = ath6kl_fwlog_release, .read = ath6kl_fwlog_read, .owner = THIS_MODULE, .llseek = default_llseek, }; +static ssize_t ath6kl_fwlog_block_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + struct ath6kl *ar = file->private_data; + struct sk_buff *skb; + ssize_t ret_cnt; + size_t len = 0, not_copied; + char *buf; + int ret; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + spin_lock(&ar->debug.fwlog_queue.lock); + + if (skb_queue_len(&ar->debug.fwlog_queue) == 0) { + /* we must init under queue lock */ + init_completion(&ar->debug.fwlog_completion); + + spin_unlock(&ar->debug.fwlog_queue.lock); + + ret = wait_for_completion_interruptible( + &ar->debug.fwlog_completion); + if (ret == -ERESTARTSYS) + return ret; + + spin_lock(&ar->debug.fwlog_queue.lock); + } + + while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) { + if (skb->len > count - len) { + /* not enough space, put skb back and leave */ + __skb_queue_head(&ar->debug.fwlog_queue, skb); + break; + } + + + memcpy(buf + len, skb->data, skb->len); + len += skb->len; + + kfree_skb(skb); + } + + spin_unlock(&ar->debug.fwlog_queue.lock); + + /* FIXME: what to do if len == 0? */ + + not_copied = copy_to_user(user_buf, buf, len); + if (not_copied != 0) { + ret_cnt = -EFAULT; + goto out; + } + + *ppos = *ppos + len; + + ret_cnt = len; + +out: + vfree(buf); + + return ret_cnt; +} + +static const struct file_operations fops_fwlog_block = { + .open = ath6kl_fwlog_open, + .release = ath6kl_fwlog_release, + .read = ath6kl_fwlog_block_read, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -637,9 +740,13 @@ static ssize_t ath6kl_endpoint_stats_read(struct file *file, return -ENOMEM; #define EPSTAT(name) \ - len = print_endpoint_stat(target, buf, buf_len, len, \ - offsetof(struct htc_endpoint_stats, name), \ - #name) + do { \ + len = print_endpoint_stat(target, buf, buf_len, len, \ + offsetof(struct htc_endpoint_stats, \ + name), \ + #name); \ + } while (0) + EPSTAT(cred_low_indicate); EPSTAT(tx_issued); EPSTAT(tx_pkt_bundled); @@ -749,17 +856,9 @@ static ssize_t ath6kl_regread_write(struct file *file, size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - u8 buf[50]; - unsigned int len; unsigned long reg_addr; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - buf[len] = '\0'; - - if (strict_strtoul(buf, 0, ®_addr)) + if (kstrtoul_from_user(user_buf, count, 0, ®_addr)) return -EINVAL; if ((reg_addr % 4) != 0) @@ -873,15 +972,8 @@ static ssize_t ath6kl_lrssi_roam_write(struct file *file, { struct ath6kl *ar = file->private_data; unsigned long lrssi_roam_threshold; - char buf[32]; - ssize_t len; - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - buf[len] = '\0'; - if (strict_strtoul(buf, 0, &lrssi_roam_threshold)) + if (kstrtoul_from_user(user_buf, count, 0, &lrssi_roam_threshold)) return -EINVAL; ar->lrssi_roam_threshold = lrssi_roam_threshold; @@ -1411,6 +1503,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file, return -EINVAL; pstream.medium_time = cpu_to_le32(val32); + pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000; + ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream); return count; @@ -1505,57 +1599,51 @@ static const struct file_operations fops_bgscan_int = { }; static ssize_t ath6kl_listen_int_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - u16 listen_int_t, listen_int_b; + struct ath6kl_vif *vif; + u16 listen_interval; char buf[32]; - char *sptr, *token; ssize_t len; + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) + if (kstrtou16(buf, 0, &listen_interval)) return -EINVAL; - if (kstrtou16(token, 0, &listen_int_t)) + if ((listen_interval < 15) || (listen_interval > 3000)) return -EINVAL; - if (kstrtou16(sptr, 0, &listen_int_b)) - return -EINVAL; - - if ((listen_int_t < 15) || (listen_int_t > 5000)) - return -EINVAL; - - if ((listen_int_b < 1) || (listen_int_b > 50)) - return -EINVAL; - - ar->listen_intvl_t = listen_int_t; - ar->listen_intvl_b = listen_int_b; - - ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t, - ar->listen_intvl_b); + vif->listen_intvl_t = listen_interval; + ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, + vif->listen_intvl_t, 0); return count; } static ssize_t ath6kl_listen_int_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) + char __user *user_buf, + size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; + struct ath6kl_vif *vif; char buf[32]; int len; - len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, - ar->listen_intvl_b); + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + len = scnprintf(buf, sizeof(buf), "%u\n", vif->listen_intvl_t); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1628,33 +1716,29 @@ static const struct file_operations fops_power_params = { .llseek = default_llseek, }; -int ath6kl_debug_init(struct ath6kl *ar) +void ath6kl_debug_init(struct ath6kl *ar) { - ar->debug.fwlog_buf.buf = vmalloc(ATH6KL_FWLOG_SIZE); - if (ar->debug.fwlog_buf.buf == NULL) - return -ENOMEM; - - ar->debug.fwlog_tmp = kmalloc(ATH6KL_FWLOG_SLOT_SIZE, GFP_KERNEL); - if (ar->debug.fwlog_tmp == NULL) { - vfree(ar->debug.fwlog_buf.buf); - return -ENOMEM; - } - - spin_lock_init(&ar->debug.fwlog_lock); + skb_queue_head_init(&ar->debug.fwlog_queue); + init_completion(&ar->debug.fwlog_completion); /* * Actually we are lying here but don't know how to read the mask * value from the firmware. */ ar->debug.fwlog_mask = 0; +} +/* + * Initialisation needs to happen in two stages as fwlog events can come + * before cfg80211 is initialised, and debugfs depends on cfg80211 + * initialisation. + */ +int ath6kl_debug_init_fs(struct ath6kl *ar) +{ ar->debugfs_phy = debugfs_create_dir("ath6kl", ar->wiphy->debugfsdir); - if (!ar->debugfs_phy) { - vfree(ar->debug.fwlog_buf.buf); - kfree(ar->debug.fwlog_tmp); + if (!ar->debugfs_phy) return -ENOMEM; - } debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar, &fops_tgt_stats); @@ -1668,6 +1752,9 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar, &fops_fwlog); + debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar, + &fops_fwlog_block); + debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar, &fops_fwlog_mask); @@ -1702,24 +1789,26 @@ int ath6kl_debug_init(struct ath6kl *ar) ar->debugfs_phy, ar, &fops_disconnect_timeout); debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar, - &fops_create_qos); + &fops_create_qos); debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar, - &fops_delete_qos); + &fops_delete_qos); debugfs_create_file("bgscan_interval", S_IWUSR, - ar->debugfs_phy, ar, &fops_bgscan_int); + ar->debugfs_phy, ar, &fops_bgscan_int); + + debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, + ar->debugfs_phy, ar, &fops_listen_int); debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, - &fops_power_params); + &fops_power_params); return 0; } void ath6kl_debug_cleanup(struct ath6kl *ar) { - vfree(ar->debug.fwlog_buf.buf); - kfree(ar->debug.fwlog_tmp); + skb_queue_purge(&ar->debug.fwlog_queue); kfree(ar->debug.roam_tbl); } diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9853c9c125c..1803a0baae8 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -41,6 +42,7 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ ATH6KL_DBG_WMI_DUMP = BIT(19), ATH6KL_DBG_SUSPEND = BIT(20), + ATH6KL_DBG_USB = BIT(21), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; @@ -55,35 +57,16 @@ int ath6kl_printk(const char *level, const char *fmt, ...); #define ath6kl_warn(fmt, ...) \ ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__) -#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask) - enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, }; #ifdef CONFIG_ATH6KL_DEBUG -#define ath6kl_dbg(mask, fmt, ...) \ - ({ \ - int rtn; \ - if (debug_mask & mask) \ - rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \ - else \ - rtn = 0; \ - \ - rtn; \ - }) - -static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, - const char *msg, const char *prefix, - const void *buf, size_t len) -{ - if (debug_mask & mask) { - if (msg) - ath6kl_dbg(mask, "%s\n", msg); - print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); - } -} +void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...); +void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, + const char *msg, const char *prefix, + const void *buf, size_t len); void ath6kl_dump_registers(struct ath6kl_device *dev, struct ath6kl_irq_proc_registers *irq_proc_reg, @@ -95,7 +78,8 @@ int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf, size_t len); void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive); void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout); -int ath6kl_debug_init(struct ath6kl *ar); +void ath6kl_debug_init(struct ath6kl *ar); +int ath6kl_debug_init_fs(struct ath6kl *ar); void ath6kl_debug_cleanup(struct ath6kl *ar); #else @@ -145,7 +129,11 @@ static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, { } -static inline int ath6kl_debug_init(struct ath6kl *ar) +static inline void ath6kl_debug_init(struct ath6kl *ar) +{ +} + +static inline int ath6kl_debug_init_fs(struct ath6kl *ar) { return 0; } diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h index 2fe1dadfc77..fd84086638e 100644 --- a/drivers/net/wireless/ath/ath6kl/hif-ops.h +++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e57da35e59f..68ed6c2665b 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,6 +16,8 @@ */ #include "hif.h" +#include <linux/export.h> + #include "core.h" #include "target.h" #include "hif-ops.h" @@ -59,6 +62,8 @@ int ath6kl_hif_rw_comp_handler(void *context, int status) return 0; } +EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler); + #define REG_DUMP_COUNT_AR6003 60 #define REGISTER_DUMP_LEN_MAX 60 @@ -85,7 +90,7 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) } ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", - regdump_addr); + regdump_addr); regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); /* fetch register dump data */ @@ -102,9 +107,9 @@ static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); - for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { + for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) { ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", - 4 * i, + i, le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), @@ -130,6 +135,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) ath6kl_warn("Failed to clear debug interrupt: %d\n", ret); ath6kl_hif_dump_fw_crash(dev->ar); + ath6kl_read_fwlogs(dev->ar); return ret; } @@ -279,7 +285,7 @@ static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev) dev->irq_en_reg.cntr_int_status_en; ath6kl_dbg(ATH6KL_DBG_IRQ, - "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", + "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", counter_int_status); /* @@ -354,7 +360,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) } ath6kl_dbg(ATH6KL_DBG_IRQ, - "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", + "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", cpu_int_status); /* Clear the interrupt */ @@ -429,9 +435,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) if (status) goto out; - if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ)) - ath6kl_dump_registers(dev, &dev->irq_proc_reg, - &dev->irq_en_reg); + ath6kl_dump_registers(dev, &dev->irq_proc_reg, + &dev->irq_en_reg); /* Update only those registers that are enabled */ host_int_status = dev->irq_proc_reg.host_int_status & @@ -561,6 +566,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar) return status; } +EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler); static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev) { @@ -689,6 +695,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); + /* usb doesn't support enabling interrupts */ + /* FIXME: remove check once USB support is implemented */ + if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) + return 0; + status = ath6kl_hif_disable_intrs(dev); fail_setup: diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h index 699a036f3a4..20ed6b73517 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.h +++ b/drivers/net/wireless/ath/ath6kl/hif.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -197,6 +198,8 @@ struct hif_scatter_req { u8 *virt_dma_buf; struct hif_scatter_item scat_list[1]; + + u32 scat_q_depth; }; struct ath6kl_irq_proc_registers { @@ -220,6 +223,7 @@ struct ath6kl_irq_enable_reg { } __packed; struct ath6kl_device { + /* protects irq_proc_reg and irq_en_reg below */ spinlock_t lock; struct ath6kl_irq_proc_registers irq_proc_reg; struct ath6kl_irq_enable_reg irq_en_reg; diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index f3b63ca25c7..4849d99cce7 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,6 +23,9 @@ #define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask)) +/* threshold to re-enable Tx bundling for an AC*/ +#define TX_RESUME_BUNDLE_THRESHOLD 1500 + /* Functions for Tx credit handling */ static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info, struct htc_endpoint_credit_dist *ep_dist, @@ -168,31 +172,29 @@ static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info, static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info, struct list_head *epdist_list) { - struct htc_endpoint_credit_dist *cur_dist_list; + struct htc_endpoint_credit_dist *cur_list; - list_for_each_entry(cur_dist_list, epdist_list, list) { - if (cur_dist_list->endpoint == ENDPOINT_0) + list_for_each_entry(cur_list, epdist_list, list) { + if (cur_list->endpoint == ENDPOINT_0) continue; - if (cur_dist_list->cred_to_dist > 0) { - cur_dist_list->credits += - cur_dist_list->cred_to_dist; - cur_dist_list->cred_to_dist = 0; - if (cur_dist_list->credits > - cur_dist_list->cred_assngd) + if (cur_list->cred_to_dist > 0) { + cur_list->credits += cur_list->cred_to_dist; + cur_list->cred_to_dist = 0; + + if (cur_list->credits > cur_list->cred_assngd) ath6kl_credit_reduce(cred_info, - cur_dist_list, - cur_dist_list->cred_assngd); + cur_list, + cur_list->cred_assngd); - if (cur_dist_list->credits > - cur_dist_list->cred_norm) - ath6kl_credit_reduce(cred_info, cur_dist_list, - cur_dist_list->cred_norm); + if (cur_list->credits > cur_list->cred_norm) + ath6kl_credit_reduce(cred_info, cur_list, + cur_list->cred_norm); - if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) { - if (cur_dist_list->txq_depth == 0) + if (!(cur_list->dist_flags & HTC_EP_ACTIVE)) { + if (cur_list->txq_depth == 0) ath6kl_credit_reduce(cred_info, - cur_dist_list, 0); + cur_list, 0); } } } @@ -460,8 +462,8 @@ static void htc_async_tx_scat_complete(struct htc_target *target, INIT_LIST_HEAD(&tx_compq); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx scat complete len %d entries %d\n", - scat_req->len, scat_req->scat_entries); + "htc tx scat complete len %d entries %d\n", + scat_req->len, scat_req->scat_entries); if (scat_req->status) ath6kl_err("send scatter req failed: %d\n", scat_req->status); @@ -599,8 +601,8 @@ static void ath6kl_htc_tx_pkts_get(struct htc_target *target, list); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx got packet 0x%p queue depth %d\n", - packet, get_queue_depth(&endpoint->txq)); + "htc tx got packet 0x%p queue depth %d\n", + packet, get_queue_depth(&endpoint->txq)); len = CALC_TXRX_PADDED_LEN(target, packet->act_len + HTC_HDR_LENGTH); @@ -670,6 +672,7 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, struct htc_packet *packet; int i, len, rem_scat, cred_pad; int status = 0; + u8 flags; rem_scat = target->max_tx_bndl_sz; @@ -696,9 +699,9 @@ static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target, scat_req->scat_list[i].packet = packet; /* prepare packet and flag message as part of a send bundle */ - ath6kl_htc_tx_prep_pkt(packet, - packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE, - cred_pad, packet->info.tx.seqno); + flags = packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE; + ath6kl_htc_tx_prep_pkt(packet, flags, + cred_pad, packet->info.tx.seqno); /* Make sure the buffer is 4-byte aligned */ ath6kl_htc_tx_buf_align(&packet->buf, packet->act_len + HTC_HDR_LENGTH); @@ -744,6 +747,12 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, struct hif_scatter_req *scat_req = NULL; int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0; int status; + u32 txb_mask; + u8 ac = WMM_NUM_AC; + + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || + (WMI_CONTROL_SVC != endpoint->svc_id)) + ac = target->dev->ar->ep2ac_map[endpoint->eid]; while (true) { status = 0; @@ -759,10 +768,35 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint, if (!scat_req) { /* no scatter resources */ ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx no more scatter resources\n"); + "htc tx no more scatter resources\n"); break; } + if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) { + if (WMM_AC_BE == ac) + /* + * BE, BK have priorities and bit + * positions reversed + */ + txb_mask = (1 << WMM_AC_BK); + else + /* + * any AC with priority lower than + * itself + */ + txb_mask = ((1 << ac) - 1); + /* + * when the scatter request resources drop below a + * certain threshold, disable Tx bundling for all + * AC's with priority lower than the current requesting + * AC. Otherwise re-enable Tx bundling for them + */ + if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS) + target->tx_bndl_mask &= ~txb_mask; + else + target->tx_bndl_mask |= txb_mask; + } + ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n", n_scat); @@ -806,6 +840,7 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, struct htc_packet *packet; int bundle_sent; int n_pkts_bundle; + u8 ac = WMM_NUM_AC; spin_lock_bh(&target->tx_lock); @@ -823,6 +858,10 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, */ INIT_LIST_HEAD(&txq); + if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) || + (WMI_CONTROL_SVC != endpoint->svc_id)) + ac = target->dev->ar->ep2ac_map[endpoint->eid]; + while (true) { if (list_empty(&endpoint->txq)) @@ -840,15 +879,18 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, while (true) { /* try to send a bundle on each pass */ - if ((target->tx_bndl_enable) && + if ((target->tx_bndl_mask) && (get_queue_depth(&txq) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) { int temp1 = 0, temp2 = 0; - ath6kl_htc_tx_bundle(endpoint, &txq, - &temp1, &temp2); - bundle_sent += temp1; - n_pkts_bundle += temp2; + /* check if bundling is enabled for an AC */ + if (target->tx_bndl_mask & (1 << ac)) { + ath6kl_htc_tx_bundle(endpoint, &txq, + &temp1, &temp2); + bundle_sent += temp1; + n_pkts_bundle += temp2; + } } if (list_empty(&txq)) @@ -867,6 +909,26 @@ static void ath6kl_htc_tx_from_queue(struct htc_target *target, endpoint->ep_st.tx_bundles += bundle_sent; endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle; + + /* + * if an AC has bundling disabled and no tx bundling + * has occured continously for a certain number of TX, + * enable tx bundling for this AC + */ + if (!bundle_sent) { + if (!(target->tx_bndl_mask & (1 << ac)) && + (ac < WMM_NUM_AC)) { + if (++target->ac_tx_count[ac] >= + TX_RESUME_BUNDLE_THRESHOLD) { + target->ac_tx_count[ac] = 0; + target->tx_bndl_mask |= (1 << ac); + } + } + } else { + /* tx bundling will reset the counter */ + if (ac < WMM_NUM_AC) + target->ac_tx_count[ac] = 0; + } } endpoint->tx_proc_cnt = 0; @@ -979,8 +1041,8 @@ static int htc_setup_tx_complete(struct htc_target *target) memcpy(&setup_comp_ext->flags, &flags, sizeof(setup_comp_ext->flags)); set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext, - sizeof(struct htc_setup_comp_ext_msg), - ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); + sizeof(struct htc_setup_comp_ext_msg), + ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); } else { struct htc_setup_comp_msg *setup_comp; @@ -988,8 +1050,8 @@ static int htc_setup_tx_complete(struct htc_target *target) memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg)); setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID); set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp, - sizeof(struct htc_setup_comp_msg), - ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); + sizeof(struct htc_setup_comp_msg), + ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG); } /* we want synchronous operation */ @@ -1088,9 +1150,9 @@ void ath6kl_htc_flush_txep(struct htc_target *target, packet->status = -ECANCELED; list_del(&packet->list); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", - packet, packet->act_len, - packet->endpoint, packet->info.tx.tag); + "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n", + packet, packet->act_len, + packet->endpoint, packet->info.tx.tag); INIT_LIST_HEAD(&container); list_add_tail(&packet->list, &container); @@ -1490,7 +1552,7 @@ static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets) if (packets->act_len > 0) { ath6kl_err("htc_ctrl_rx, got message with len:%zu\n", - packets->act_len + HTC_HDR_LENGTH); + packets->act_len + HTC_HDR_LENGTH); ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx unexpected endpoint 0 message", "", @@ -1609,8 +1671,8 @@ static int htc_parse_trailer(struct htc_target *target, } lk_ahd = (struct htc_lookahead_report *) record_buf; - if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) - && next_lk_ahds) { + if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF)) && + next_lk_ahds) { ath6kl_dbg(ATH6KL_DBG_HTC, "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n", @@ -2038,13 +2100,13 @@ fail_rx: list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) { list_del(&packet->list); htc_reclaim_rxbuf(target, packet, - &target->endpoint[packet->endpoint]); + &target->endpoint[packet->endpoint]); } list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) { list_del(&packet->list); htc_reclaim_rxbuf(target, packet, - &target->endpoint[packet->endpoint]); + &target->endpoint[packet->endpoint]); } return status; @@ -2062,6 +2124,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, enum htc_endpoint_id id; int n_fetched = 0; + INIT_LIST_HEAD(&comp_pktq); *num_pkts = 0; /* @@ -2175,11 +2238,11 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target) u32 look_ahead; if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead, - HTC_TARGET_RESPONSE_TIMEOUT)) + HTC_TARGET_RESPONSE_TIMEOUT)) return NULL; ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); + "htc rx wait ctrl look_ahead 0x%X\n", look_ahead); htc_hdr = (struct htc_frame_hdr *)&look_ahead; @@ -2244,7 +2307,7 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, depth = get_queue_depth(pkt_queue); ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx add multiple ep id %d cnt %d len %d\n", + "htc rx add multiple ep id %d cnt %d len %d\n", first_pkt->endpoint, depth, first_pkt->buf_len); endpoint = &target->endpoint[first_pkt->endpoint]; @@ -2270,8 +2333,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target, if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) { if (target->ep_waiting == first_pkt->endpoint) { ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx blocked on ep %d, unblocking\n", - target->ep_waiting); + "htc rx blocked on ep %d, unblocking\n", + target->ep_waiting); target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS; target->ep_waiting = ENDPOINT_MAX; rx_unblock = true; @@ -2308,7 +2371,21 @@ void ath6kl_htc_flush_rx_buf(struct htc_target *target) "htc rx flush pkt 0x%p len %d ep %d\n", packet, packet->buf_len, packet->endpoint); - dev_kfree_skb(packet->pkt_cntxt); + /* + * packets in rx_bufq of endpoint 0 have originally + * been queued from target->free_ctrl_rxbuf where + * packet and packet->buf_start are allocated + * separately using kmalloc(). For other endpoint + * rx_bufq, it is allocated as skb where packet is + * skb->head. Take care of this difference while freeing + * the memory. + */ + if (packet->endpoint == ENDPOINT_0) { + kfree(packet->buf_start); + kfree(packet); + } else { + dev_kfree_skb(packet->pkt_cntxt); + } spin_lock_bh(&target->rx_lock); } spin_unlock_bh(&target->rx_lock); @@ -2327,6 +2404,7 @@ int ath6kl_htc_conn_service(struct htc_target *target, enum htc_endpoint_id assigned_ep = ENDPOINT_MAX; unsigned int max_msg_sz = 0; int status = 0; + u16 msg_id; ath6kl_dbg(ATH6KL_DBG_HTC, "htc connect service target 0x%p service id 0x%x\n", @@ -2370,9 +2448,10 @@ int ath6kl_htc_conn_service(struct htc_target *target, } resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf; + msg_id = le16_to_cpu(resp_msg->msg_id); - if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID) - || (rx_pkt->act_len < sizeof(*resp_msg))) { + if ((msg_id != HTC_MSG_CONN_SVC_RESP_ID) || + (rx_pkt->act_len < sizeof(*resp_msg))) { status = -ENOMEM; goto fail_tx; } @@ -2419,6 +2498,15 @@ int ath6kl_htc_conn_service(struct htc_target *target, endpoint->cred_dist.endpoint = assigned_ep; endpoint->cred_dist.cred_sz = target->tgt_cred_sz; + switch (endpoint->svc_id) { + case WMI_DATA_BK_SVC: + endpoint->tx_drop_packet_threshold = MAX_DEF_COOKIE_NUM / 3; + break; + default: + endpoint->tx_drop_packet_threshold = MAX_HI_COOKIE_NUM; + break; + } + if (conn_req->max_rxmsg_sz) { /* * Override cred_per_msg calculation, this optimizes @@ -2516,7 +2604,8 @@ static void htc_setup_msg_bndl(struct htc_target *target) target->max_rx_bndl_sz, target->max_tx_bndl_sz); if (target->max_tx_bndl_sz) - target->tx_bndl_enable = true; + /* tx_bndl_mask is enabled per AC, each has 1 bit */ + target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1; if (target->max_rx_bndl_sz) target->rx_bndl_enable = true; @@ -2531,7 +2620,7 @@ static void htc_setup_msg_bndl(struct htc_target *target) * padding will spill into the next credit buffer * which is fatal. */ - target->tx_bndl_enable = false; + target->tx_bndl_mask = 0; } } @@ -2543,6 +2632,12 @@ int ath6kl_htc_wait_target(struct htc_target *target) struct htc_service_connect_resp resp; int status; + /* FIXME: remove once USB support is implemented */ + if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ath6kl_err("HTC doesn't support USB yet. Patience!\n"); + return -EOPNOTSUPP; + } + /* we should be getting 1 control message that the target is ready */ packet = htc_wait_for_ctrl_msg(target); @@ -2582,8 +2677,8 @@ int ath6kl_htc_wait_target(struct htc_target *target) } ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n", - (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", - target->htc_tgt_ver); + (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", + target->htc_tgt_ver); if (target->msg_per_bndl_max > 0) htc_setup_msg_bndl(target); @@ -2772,17 +2867,19 @@ void ath6kl_htc_cleanup(struct htc_target *target) { struct htc_packet *packet, *tmp_packet; - ath6kl_hif_cleanup_scatter(target->dev->ar); + /* FIXME: remove check once USB support is implemented */ + if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) + ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, - &target->free_ctrl_txbuf, list) { + &target->free_ctrl_txbuf, list) { list_del(&packet->list); kfree(packet->buf_start); kfree(packet); } list_for_each_entry_safe(packet, tmp_packet, - &target->free_ctrl_rxbuf, list) { + &target->free_ctrl_rxbuf, list) { list_del(&packet->list); kfree(packet->buf_start); kfree(packet); diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h index 57672e1ed1a..5027ccc36b6 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.h +++ b/drivers/net/wireless/ath/ath6kl/htc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -87,6 +88,8 @@ #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) #define WMI_MAX_SERVICES 5 +#define WMM_NUM_AC 4 + /* reserved and used to flush ALL packets */ #define HTC_TX_PACKET_TAG_ALL 0 #define HTC_SERVICE_TX_PACKET_TAG 1 @@ -498,6 +501,7 @@ struct htc_endpoint { u8 seqno; u32 conn_flags; struct htc_endpoint_stats ep_st; + u16 tx_drop_packet_threshold; }; struct htc_control_buffer { @@ -519,9 +523,16 @@ struct htc_target { struct ath6kl_htc_credit_info *credit_info; int tgt_creds; unsigned int tgt_cred_sz; + + /* protects free_ctrl_txbuf and free_ctrl_rxbuf */ spinlock_t htc_lock; + + /* FIXME: does this protext rx_bufq and endpoint structures or what? */ spinlock_t rx_lock; + + /* protects endpoint->txq */ spinlock_t tx_lock; + struct ath6kl_device *dev; u32 htc_flags; u32 rx_st_flags; @@ -531,7 +542,7 @@ struct htc_target { /* max messages per bundle for HTC */ int msg_per_bndl_max; - bool tx_bndl_enable; + u32 tx_bndl_mask; int rx_bndl_enable; int max_rx_bndl_sz; int max_tx_bndl_sz; @@ -543,6 +554,9 @@ struct htc_target { int max_xfer_szper_scatreq; int chk_irq_status_cnt; + + /* counts the number of Tx without bundling continously per AC */ + u32 ac_tx_count[WMM_NUM_AC]; }; void *ath6kl_htc_create(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7f55be3092d..03cae142f17 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,22 +18,16 @@ #include <linux/moduleparam.h> #include <linux/errno.h> +#include <linux/export.h> #include <linux/of.h> #include <linux/mmc/sdio_func.h> + #include "core.h" #include "cfg80211.h" #include "target.h" #include "debug.h" #include "hif-ops.h" -unsigned int debug_mask; -static unsigned int testmode; -static bool suspend_cutpower; - -module_param(debug_mask, uint, 0644); -module_param(testmode, uint, 0644); -module_param(suspend_cutpower, bool, 0444); - static const struct ath6kl_hw hw_list[] = { { .id = AR6003_HW_2_0_VERSION, @@ -47,11 +42,14 @@ static const struct ath6kl_hw hw_list[] = { /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, - .fw_otp = AR6003_HW_2_0_OTP_FILE, - .fw = AR6003_HW_2_0_FIRMWARE_FILE, - .fw_tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, - .fw_patch = AR6003_HW_2_0_PATCH_FILE, - .fw_api2 = AR6003_HW_2_0_FIRMWARE_2_FILE, + .fw = { + .dir = AR6003_HW_2_0_FW_DIR, + .otp = AR6003_HW_2_0_OTP_FILE, + .fw = AR6003_HW_2_0_FIRMWARE_FILE, + .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, + .patch = AR6003_HW_2_0_PATCH_FILE, + }, + .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE, }, @@ -64,14 +62,20 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 512, .refclk_hz = 26000000, .uarttx_pin = 8, + .testscript_addr = 0x57ef74, + + .fw = { + .dir = AR6003_HW_2_1_1_FW_DIR, + .otp = AR6003_HW_2_1_1_OTP_FILE, + .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, + .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, + .patch = AR6003_HW_2_1_1_PATCH_FILE, + .utf = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE, + .testscript = AR6003_HW_2_1_1_TESTSCRIPT_FILE, + }, - .fw_otp = AR6003_HW_2_1_1_OTP_FILE, - .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, - .fw_tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, - .fw_patch = AR6003_HW_2_1_1_PATCH_FILE, - .fw_api2 = AR6003_HW_2_1_1_FIRMWARE_2_FILE, .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, - .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, + .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, }, { .id = AR6004_HW_1_0_VERSION, @@ -84,8 +88,11 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 11, - .fw = AR6004_HW_1_0_FIRMWARE_FILE, - .fw_api2 = AR6004_HW_1_0_FIRMWARE_2_FILE, + .fw = { + .dir = AR6004_HW_1_0_FW_DIR, + .fw = AR6004_HW_1_0_FIRMWARE_FILE, + }, + .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE, }, @@ -100,8 +107,11 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 40000000, .uarttx_pin = 11, - .fw = AR6004_HW_1_1_FIRMWARE_FILE, - .fw_api2 = AR6004_HW_1_1_FIRMWARE_2_FILE, + .fw = { + .dir = AR6004_HW_1_1_FW_DIR, + .fw = AR6004_HW_1_1_FIRMWARE_FILE, + }, + .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, }, @@ -342,11 +352,7 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, blk_size |= ((u32)htc_ctrl_buf) << 16; /* set the host interest area for the block size */ - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_mbox_io_block_sz)), - (u8 *)&blk_size, - 4); + status = ath6kl_bmi_write_hi32(ar, hi_mbox_io_block_sz, blk_size); if (status) { ath6kl_err("bmi_write_memory for IO block size failed\n"); goto out; @@ -358,11 +364,8 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val, if (mbox_isr_yield_val) { /* set the host interest area for the mbox ISR yield limit */ - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_mbox_isr_yield_limit)), - (u8 *)&mbox_isr_yield_val, - 4); + status = ath6kl_bmi_write_hi32(ar, hi_mbox_isr_yield_limit, + mbox_isr_yield_val); if (status) { ath6kl_err("bmi_write_memory for yield limit failed\n"); goto out; @@ -375,7 +378,6 @@ out: static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) { - int status = 0; int ret; /* @@ -383,43 +385,54 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) * default values. Required if checksum offload is needed. Set * RxMetaVersion to 2. */ - if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, - ar->rx_meta_ver, 0, 0)) { - ath6kl_err("unable to set the rx frame format\n"); - status = -EIO; + ret = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx, + ar->rx_meta_ver, 0, 0); + if (ret) { + ath6kl_err("unable to set the rx frame format: %d\n", ret); + return ret; } - if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) - if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1, - IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { - ath6kl_err("unable to set power save fail event policy\n"); - status = -EIO; + if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) { + ret = ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1, + IGNORE_PS_FAIL_DURING_SCAN); + if (ret) { + ath6kl_err("unable to set power save fail event policy: %d\n", + ret); + return ret; } + } - if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) - if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0, - WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) { - ath6kl_err("unable to set barker preamble policy\n"); - status = -EIO; + if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER)) { + ret = ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0, + WMI_FOLLOW_BARKER_IN_ERP); + if (ret) { + ath6kl_err("unable to set barker preamble policy: %d\n", + ret); + return ret; } + } - if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx, - WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) { - ath6kl_err("unable to set keep alive interval\n"); - status = -EIO; + ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx, + WLAN_CONFIG_KEEP_ALIVE_INTERVAL); + if (ret) { + ath6kl_err("unable to set keep alive interval: %d\n", ret); + return ret; } - if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, - WLAN_CONFIG_DISCONNECT_TIMEOUT)) { - ath6kl_err("unable to set disconnect timeout\n"); - status = -EIO; + ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, idx, + WLAN_CONFIG_DISCONNECT_TIMEOUT); + if (ret) { + ath6kl_err("unable to set disconnect timeout: %d\n", ret); + return ret; } - if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) - if (ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED)) { - ath6kl_err("unable to set txop bursting\n"); - status = -EIO; + if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST)) { + ret = ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED); + if (ret) { + ath6kl_err("unable to set txop bursting: %d\n", ret); + return ret; } + } if (ar->p2p && (ar->vif_max == 1 || idx)) { ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx, @@ -443,7 +456,7 @@ static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx) } } - return status; + return ret; } int ath6kl_configure_target(struct ath6kl *ar) @@ -452,6 +465,12 @@ int ath6kl_configure_target(struct ath6kl *ar) u8 fw_iftype, fw_mode = 0, fw_submode = 0; int i, status; + param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG); + if (ath6kl_bmi_write_hi32(ar, hi_serial_enable, param)) { + ath6kl_err("bmi_write_memory for uart debug failed\n"); + return -EIO; + } + /* * Note: Even though the firmware interface type is * chosen as BSS_STA for all three interfaces, can @@ -483,11 +502,8 @@ int ath6kl_configure_target(struct ath6kl *ar) if (ar->p2p && ar->vif_max == 1) fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; - param = HTC_PROTOCOL_VERSION; - if (ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_app_host_interest)), - (u8 *)¶m, 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest, + HTC_PROTOCOL_VERSION) != 0) { ath6kl_err("bmi_write_memory for htc version failed\n"); return -EIO; } @@ -495,10 +511,7 @@ int ath6kl_configure_target(struct ath6kl *ar) /* set the firmware mode to STA/IBSS/AP */ param = 0; - if (ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_option_flag)), - (u8 *)¶m, 4) != 0) { + if (ath6kl_bmi_read_hi32(ar, hi_option_flag, ¶m) != 0) { ath6kl_err("bmi_read_memory for setting fwmode failed\n"); return -EIO; } @@ -510,11 +523,7 @@ int ath6kl_configure_target(struct ath6kl *ar) param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); - if (ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_option_flag)), - (u8 *)¶m, - 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_option_flag, param) != 0) { ath6kl_err("bmi_write_memory for setting fwmode failed\n"); return -EIO; } @@ -533,16 +542,13 @@ int ath6kl_configure_target(struct ath6kl *ar) param = ar->hw.board_ext_data_addr; ram_reserved_size = ar->hw.reserved_ram_size; - if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_ext_data)), - (u8 *)¶m, 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) { ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); return -EIO; } - if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_end_ram_reserve_sz)), - (u8 *)&ram_reserved_size, 4) != 0) { + if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, + ram_reserved_size) != 0) { ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); return -EIO; } @@ -553,56 +559,19 @@ int ath6kl_configure_target(struct ath6kl *ar) return -EIO; /* Configure GPIO AR600x UART */ - param = ar->hw.uarttx_pin; - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_dbg_uart_txpin)), - (u8 *)¶m, 4); + status = ath6kl_bmi_write_hi32(ar, hi_dbg_uart_txpin, + ar->hw.uarttx_pin); if (status) return status; /* Configure target refclk_hz */ - param = ar->hw.refclk_hz; - status = ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_refclk_hz)), - (u8 *)¶m, 4); + status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz); if (status) return status; return 0; } -void ath6kl_core_free(struct ath6kl *ar) -{ - wiphy_free(ar->wiphy); -} - -void ath6kl_core_cleanup(struct ath6kl *ar) -{ - ath6kl_hif_power_off(ar); - - destroy_workqueue(ar->ath6kl_wq); - - if (ar->htc_target) - ath6kl_htc_cleanup(ar->htc_target); - - ath6kl_cookie_cleanup(ar); - - ath6kl_cleanup_amsdu_rxbufs(ar); - - ath6kl_bmi_cleanup(ar); - - ath6kl_debug_cleanup(ar); - - kfree(ar->fw_board); - kfree(ar->fw_otp); - kfree(ar->fw); - kfree(ar->fw_patch); - - ath6kl_deinit_ieee80211_hw(ar); -} - /* firmware upload */ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, u8 **fw, size_t *fw_len) @@ -626,21 +595,6 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, } #ifdef CONFIG_OF -static const char *get_target_ver_dir(const struct ath6kl *ar) -{ - switch (ar->version.target_ver) { - case AR6003_HW_1_0_VERSION: - return "ath6k/AR6003/hw1.0"; - case AR6003_HW_2_0_VERSION: - return "ath6k/AR6003/hw2.0"; - case AR6003_HW_2_1_1_VERSION: - return "ath6k/AR6003/hw2.1.1"; - } - ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__, - ar->version.target_ver); - return NULL; -} - /* * Check the device tree for a board-id and use it to construct * the pathname to the firmware file. Used (for now) to find a @@ -663,7 +617,7 @@ static bool check_device_tree(struct ath6kl *ar) continue; } snprintf(board_filename, sizeof(board_filename), - "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id); + "%s/bdata.%s.bin", ar->hw.fw.dir, board_id); ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board, &ar->fw_board_len); @@ -730,19 +684,20 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar) static int ath6kl_fetch_otp_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw_otp != NULL) return 0; - if (ar->hw.fw_otp == NULL) { + if (ar->hw.fw.otp == NULL) { ath6kl_dbg(ATH6KL_DBG_BOOT, "no OTP file configured for this hw\n"); return 0; } - filename = ar->hw.fw_otp; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.otp); ret = ath6kl_get_fw(ar, filename, &ar->fw_otp, &ar->fw_otp_len); @@ -755,33 +710,61 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar) return 0; } -static int ath6kl_fetch_fw_file(struct ath6kl *ar) +static int ath6kl_fetch_testmode_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; - if (ar->fw != NULL) + if (ar->testmode == 0) return 0; - if (testmode) { - if (ar->hw.fw_tcmd == NULL) { - ath6kl_warn("testmode not supported\n"); + ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode); + + if (ar->testmode == 2) { + if (ar->hw.fw.utf == NULL) { + ath6kl_warn("testmode 2 not supported\n"); return -EOPNOTSUPP; } - filename = ar->hw.fw_tcmd; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.utf); + } else { + if (ar->hw.fw.tcmd == NULL) { + ath6kl_warn("testmode 1 not supported\n"); + return -EOPNOTSUPP; + } - set_bit(TESTMODE, &ar->flag); + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); + } + + set_bit(TESTMODE, &ar->flag); - goto get_fw; + ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); + if (ret) { + ath6kl_err("Failed to get testmode %d firmware file %s: %d\n", + ar->testmode, filename, ret); + return ret; } - if (WARN_ON(ar->hw.fw == NULL)) + return 0; +} + +static int ath6kl_fetch_fw_file(struct ath6kl *ar) +{ + char filename[100]; + int ret; + + if (ar->fw != NULL) + return 0; + + /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */ + if (WARN_ON(ar->hw.fw.fw == NULL)) return -EINVAL; - filename = ar->hw.fw; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.fw); -get_fw: ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); if (ret) { ath6kl_err("Failed to get firmware file %s: %d\n", @@ -794,16 +777,17 @@ get_fw: static int ath6kl_fetch_patch_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw_patch != NULL) return 0; - if (ar->hw.fw_patch == NULL) + if (ar->hw.fw.patch == NULL) return 0; - filename = ar->hw.fw_patch; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.patch); ret = ath6kl_get_fw(ar, filename, &ar->fw_patch, &ar->fw_patch_len); @@ -816,6 +800,34 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar) return 0; } +static int ath6kl_fetch_testscript_file(struct ath6kl *ar) +{ + char filename[100]; + int ret; + + if (ar->testmode != 2) + return 0; + + if (ar->fw_testscript != NULL) + return 0; + + if (ar->hw.fw.testscript == NULL) + return 0; + + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.testscript); + + ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript, + &ar->fw_testscript_len); + if (ret) { + ath6kl_err("Failed to get testscript file %s: %d\n", + filename, ret); + return ret; + } + + return 0; +} + static int ath6kl_fetch_fw_api1(struct ath6kl *ar) { int ret; @@ -832,23 +844,24 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar) if (ret) return ret; + ret = ath6kl_fetch_testscript_file(ar); + if (ret) + return ret; + return 0; } -static int ath6kl_fetch_fw_api2(struct ath6kl *ar) +static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) { size_t magic_len, len, ie_len; const struct firmware *fw; struct ath6kl_fw_ie *hdr; - const char *filename; + char filename[100]; const u8 *data; int ret, ie_id, i, index, bit; __le32 *val; - if (ar->hw.fw_api2 == NULL) - return -EOPNOTSUPP; - - filename = ar->hw.fw_api2; + snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name); ret = request_firmware(&fw, filename, ar->dev); if (ret) @@ -892,7 +905,7 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) switch (ie_id) { case ATH6KL_FW_IE_OTP_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", - ie_len); + ie_len); ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL); @@ -905,7 +918,11 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) break; case ATH6KL_FW_IE_FW_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", - ie_len); + ie_len); + + /* in testmode we already might have a fw file */ + if (ar->fw != NULL) + break; ar->fw = kmemdup(data, ie_len, GFP_KERNEL); @@ -918,7 +935,7 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) break; case ATH6KL_FW_IE_PATCH_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n", - ie_len); + ie_len); ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL); @@ -1010,7 +1027,7 @@ out: return ret; } -static int ath6kl_fetch_firmwares(struct ath6kl *ar) +int ath6kl_init_fetch_firmwares(struct ath6kl *ar) { int ret; @@ -1018,17 +1035,30 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; - ret = ath6kl_fetch_fw_api2(ar); + ret = ath6kl_fetch_testmode_file(ar); + if (ret) + return ret; + + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { - ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n"); - return 0; + ar->fw_api = 3; + goto out; + } + + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE); + if (ret == 0) { + ar->fw_api = 2; + goto out; } ret = ath6kl_fetch_fw_api1(ar); if (ret) return ret; - ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n"); + ar->fw_api = 1; + +out: + ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api); return 0; } @@ -1049,22 +1079,14 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) */ if (ar->hw.board_addr != 0) { board_address = ar->hw.board_addr; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_data)), - (u8 *) &board_address, 4); + ath6kl_bmi_write_hi32(ar, hi_board_data, + board_address); } else { - ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_data)), - (u8 *) &board_address, 4); + ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address); } /* determine where in target ram to write extended board data */ - ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_ext_data)), - (u8 *) &board_ext_address, 4); + ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address); if (ar->target_type == TARGET_TYPE_AR6003 && board_ext_address == 0) { @@ -1076,6 +1098,8 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) case TARGET_TYPE_AR6003: board_data_size = AR6003_BOARD_DATA_SZ; board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ; + if (ar->fw_board_len > (board_data_size + board_ext_data_size)) + board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2; break; case TARGET_TYPE_AR6004: board_data_size = AR6004_BOARD_DATA_SZ; @@ -1107,10 +1131,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) /* record that extended board data is initialized */ param = (board_ext_data_size << 16) | 1; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_ext_data_config)), - (unsigned char *) ¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_board_ext_data_config, param); } if (ar->fw_board_len < board_data_size) { @@ -1131,11 +1152,7 @@ static int ath6kl_upload_board_file(struct ath6kl *ar) } /* record the fact that Board Data IS initialized */ - param = 1; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_board_data_initialized)), - (u8 *)¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1); return ret; } @@ -1162,10 +1179,7 @@ static int ath6kl_upload_otp(struct ath6kl *ar) } /* read firmware start address */ - ret = ath6kl_bmi_read(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_app_start)), - (u8 *) &address, sizeof(address)); + ret = ath6kl_bmi_read_hi32(ar, hi_app_start, &address); if (ret) { ath6kl_err("Failed to read hi_app_start: %d\n", ret); @@ -1223,7 +1237,7 @@ static int ath6kl_upload_firmware(struct ath6kl *ar) static int ath6kl_upload_patch(struct ath6kl *ar) { - u32 address, param; + u32 address; int ret; if (ar->fw_patch == NULL) @@ -1240,11 +1254,37 @@ static int ath6kl_upload_patch(struct ath6kl *ar) return ret; } - param = address; - ath6kl_bmi_write(ar, - ath6kl_get_hi_item_addr(ar, - HI_ITEM(hi_dset_list_head)), - (unsigned char *) ¶m, 4); + ath6kl_bmi_write_hi32(ar, hi_dset_list_head, address); + + return 0; +} + +static int ath6kl_upload_testscript(struct ath6kl *ar) +{ + u32 address; + int ret; + + if (ar->testmode != 2) + return 0; + + if (ar->fw_testscript == NULL) + return 0; + + address = ar->hw.testscript_addr; + + ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n", + address, ar->fw_testscript_len); + + ret = ath6kl_bmi_write(ar, address, ar->fw_testscript, + ar->fw_testscript_len); + if (ret) { + ath6kl_err("Failed to write testscript file: %d\n", ret); + return ret; + } + + ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address); + ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096); + ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1); return 0; } @@ -1255,7 +1295,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) int status = 0; if (ar->target_type != TARGET_TYPE_AR6003 && - ar->target_type != TARGET_TYPE_AR6004) + ar->target_type != TARGET_TYPE_AR6004) return -EINVAL; /* temporarily disable system sleep */ @@ -1312,7 +1352,8 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; /* WAR to avoid SDIO CRC err */ - if (ar->version.target_ver == AR6003_HW_2_0_VERSION) { + if (ar->version.target_ver == AR6003_HW_2_0_VERSION || + ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { ath6kl_err("temporary war to avoid sdio crc error\n"); param = 0x20; @@ -1357,6 +1398,11 @@ static int ath6kl_init_upload(struct ath6kl *ar) if (status) return status; + /* Download the test script */ + status = ath6kl_upload_testscript(ar); + if (status) + return status; + /* Restore system sleep */ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; status = ath6kl_bmi_reg_write(ar, address, sleep); @@ -1372,9 +1418,9 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; } -static int ath6kl_init_hw_params(struct ath6kl *ar) +int ath6kl_init_hw_params(struct ath6kl *ar) { - const struct ath6kl_hw *hw; + const struct ath6kl_hw *uninitialized_var(hw); int i; for (i = 0; i < ARRAY_SIZE(hw_list); i++) { @@ -1481,10 +1527,11 @@ int ath6kl_init_hw_start(struct ath6kl *ar) if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { - ath6kl_info("%s %s fw %s%s\n", + ath6kl_info("%s %s fw %s api %d%s\n", ar->hw.name, ath6kl_init_get_hif_name(ar->hif_type), ar->wiphy->fw_version, + ar->fw_api, test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); } @@ -1549,173 +1596,7 @@ int ath6kl_init_hw_stop(struct ath6kl *ar) return 0; } -int ath6kl_core_init(struct ath6kl *ar) -{ - struct ath6kl_bmi_target_info targ_info; - struct net_device *ndev; - int ret = 0, i; - - ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); - if (!ar->ath6kl_wq) - return -ENOMEM; - - ret = ath6kl_bmi_init(ar); - if (ret) - goto err_wq; - - /* - * Turn on power to get hardware (target) version and leave power - * on delibrately as we will boot the hardware anyway within few - * seconds. - */ - ret = ath6kl_hif_power_on(ar); - if (ret) - goto err_bmi_cleanup; - - ret = ath6kl_bmi_get_target_info(ar, &targ_info); - if (ret) - goto err_power_off; - - ar->version.target_ver = le32_to_cpu(targ_info.version); - ar->target_type = le32_to_cpu(targ_info.type); - ar->wiphy->hw_version = le32_to_cpu(targ_info.version); - - ret = ath6kl_init_hw_params(ar); - if (ret) - goto err_power_off; - - ar->htc_target = ath6kl_htc_create(ar); - - if (!ar->htc_target) { - ret = -ENOMEM; - goto err_power_off; - } - - ret = ath6kl_fetch_firmwares(ar); - if (ret) - goto err_htc_cleanup; - - /* FIXME: we should free all firmwares in the error cases below */ - - /* Indicate that WMI is enabled (although not ready yet) */ - set_bit(WMI_ENABLED, &ar->flag); - ar->wmi = ath6kl_wmi_init(ar); - if (!ar->wmi) { - ath6kl_err("failed to initialize wmi\n"); - ret = -EIO; - goto err_htc_cleanup; - } - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - - ret = ath6kl_register_ieee80211_hw(ar); - if (ret) - goto err_node_cleanup; - - ret = ath6kl_debug_init(ar); - if (ret) { - wiphy_unregister(ar->wiphy); - goto err_node_cleanup; - } - - for (i = 0; i < ar->vif_max; i++) - ar->avail_idx_map |= BIT(i); - - rtnl_lock(); - - /* Add an initial station interface */ - ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, - INFRA_NETWORK); - - rtnl_unlock(); - - if (!ndev) { - ath6kl_err("Failed to instantiate a network device\n"); - ret = -ENOMEM; - wiphy_unregister(ar->wiphy); - goto err_debug_init; - } - - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", - __func__, ndev->name, ndev, ar); - - /* setup access class priority mappings */ - ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ - ar->ac_stream_pri_map[WMM_AC_BE] = 1; - ar->ac_stream_pri_map[WMM_AC_VI] = 2; - ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ - - /* give our connected endpoints some buffers */ - ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); - ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); - - /* allocate some buffers that handle larger AMSDU frames */ - ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); - - ath6kl_cookie_init(ar); - - ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | - ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - - if (suspend_cutpower) - ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; - - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | - WIPHY_FLAG_HAVE_AP_SME | - WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - - ar->wiphy->probe_resp_offload = - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; - - set_bit(FIRST_BOOT, &ar->flag); - - ret = ath6kl_init_hw_start(ar); - if (ret) { - ath6kl_err("Failed to start hardware: %d\n", ret); - goto err_rxbuf_cleanup; - } - - /* - * Set mac address which is received in ready event - * FIXME: Move to ath6kl_interface_add() - */ - memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); - - return ret; - -err_rxbuf_cleanup: - ath6kl_htc_flush_rx_buf(ar->htc_target); - ath6kl_cleanup_amsdu_rxbufs(ar); - rtnl_lock(); - ath6kl_deinit_if_data(netdev_priv(ndev)); - rtnl_unlock(); - wiphy_unregister(ar->wiphy); -err_debug_init: - ath6kl_debug_cleanup(ar); -err_node_cleanup: - ath6kl_wmi_shutdown(ar->wmi); - clear_bit(WMI_ENABLED, &ar->flag); - ar->wmi = NULL; -err_htc_cleanup: - ath6kl_htc_cleanup(ar->htc_target); -err_power_off: - ath6kl_hif_power_off(ar); -err_bmi_cleanup: - ath6kl_bmi_cleanup(ar); -err_wq: - destroy_workqueue(ar->ath6kl_wq); - - return ret; -} - +/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) { static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -1747,6 +1628,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) void ath6kl_stop_txrx(struct ath6kl *ar) { struct ath6kl_vif *vif, *tmp_vif; + int i; set_bit(DESTROY_IN_PROGRESS, &ar->flag); @@ -1755,13 +1637,16 @@ void ath6kl_stop_txrx(struct ath6kl *ar) return; } + for (i = 0; i < AP_MAX_NUM_STA; i++) + aggr_reset_state(ar->sta_list[i].aggr_conn); + spin_lock_bh(&ar->list_lock); list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { list_del(&vif->list); spin_unlock_bh(&ar->list_lock); ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); rtnl_lock(); - ath6kl_deinit_if_data(vif); + ath6kl_cfg80211_vif_cleanup(vif); rtnl_unlock(); spin_lock_bh(&ar->list_lock); } @@ -1791,8 +1676,11 @@ void ath6kl_stop_txrx(struct ath6kl *ar) * configure NOT to reset the target during a debug session. */ ath6kl_dbg(ATH6KL_DBG_TRC, - "attempting to reset target on instance destroy\n"); + "attempting to reset target on instance destroy\n"); ath6kl_reset_device(ar, ar->target_type, true, true); clear_bit(WLAN_ENABLED, &ar->flag); + + up(&ar->sem); } +EXPORT_SYMBOL(ath6kl_stop_txrx); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index eea3c747653..229e1922ebe 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -52,9 +53,11 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) return conn; } -static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) +static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, + u8 *wpaie, size_t ielen, u8 keymgmt, + u8 ucipher, u8 auth, u8 apsd_info) { + struct ath6kl *ar = vif->ar; struct ath6kl_sta *sta; u8 free_slot; @@ -68,18 +71,31 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, sta->keymgmt = keymgmt; sta->ucipher = ucipher; sta->auth = auth; + sta->apsd_info = apsd_info; ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); + aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn); } static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) { struct ath6kl_sta *sta = &ar->sta_list[i]; + struct ath6kl_mgmt_buff *entry, *tmp; /* empty the queued pkts in the PS queue if any */ spin_lock_bh(&sta->psq_lock); skb_queue_purge(&sta->psq); + skb_queue_purge(&sta->apsdq); + + if (sta->mgmt_psq_len != 0) { + list_for_each_entry_safe(entry, tmp, &sta->mgmt_psq, list) { + kfree(entry); + } + INIT_LIST_HEAD(&sta->mgmt_psq); + sta->mgmt_psq_len = 0; + } + spin_unlock_bh(&sta->psq_lock); memset(&ar->ap_stats.sta[sta->aid - 1], 0, @@ -90,7 +106,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) sta->sta_flags = 0; ar->sta_list_index = ar->sta_list_index & ~(1 << i); - + aggr_reset_state(sta->aggr_conn); } static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason) @@ -252,7 +268,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) struct ath6kl_dbglog_hdr debug_hdr; struct ath6kl_dbglog_buf debug_buf; u32 address, length, dropped, firstbuf, debug_hdr_addr; - int ret = 0, loop; + int ret, loop; u8 *buf; buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL); @@ -334,7 +350,7 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, __le32 data; if (target_type != TARGET_TYPE_AR6003 && - target_type != TARGET_TYPE_AR6004) + target_type != TARGET_TYPE_AR6004) return; data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) : @@ -347,9 +363,6 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, case TARGET_TYPE_AR6004: address = AR6004_RESET_CONTROL_ADDRESS; break; - default: - address = AR6003_RESET_CONTROL_ADDRESS; - break; } status = ath6kl_diag_write32(ar, address, data); @@ -363,7 +376,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) u8 index; u8 keyusage; - for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { + for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) { if (vif->wep_key_list[index].key_len) { keyusage = GROUP_USAGE; if (index == vif->def_txkey_index) @@ -428,9 +441,8 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, - u8 assoc_req_len, u8 *assoc_info) + u8 assoc_req_len, u8 *assoc_info, u8 apsd_info) { - struct ath6kl *ar = vif->ar; u8 *ies = NULL, *wpa_ie = NULL, *pos; size_t ies_len = 0; struct station_info sinfo; @@ -484,9 +496,9 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, pos += 2 + pos[1]; } - ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie, + ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie, wpa_ie ? 2 + wpa_ie[1] : 0, - keymgmt, ucipher, auth); + keymgmt, ucipher, auth, apsd_info); /* send event to application */ memset(&sinfo, 0, sizeof(sinfo)); @@ -589,8 +601,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, if ((vif->nw_type == INFRA_NETWORK)) ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, - ar->listen_intvl_t, - ar->listen_intvl_b); + vif->listen_intvl_t, 0); netif_wake_queue(vif->ndev); @@ -601,7 +612,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, netif_carrier_on(vif->ndev); spin_unlock_bh(&vif->if_lock); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(vif->aggr_cntxt->aggr_conn); vif->reconnect_flag = 0; if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { @@ -808,6 +819,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) struct sk_buff *skb; bool psq_empty = false; struct ath6kl *ar = vif->ar; + struct ath6kl_mgmt_buff *mgmt_buf; conn = ath6kl_find_sta_by_aid(ar, aid); @@ -818,7 +830,7 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) * becomes empty update the PVB for this station. */ spin_lock_bh(&conn->psq_lock); - psq_empty = skb_queue_empty(&conn->psq); + psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0); spin_unlock_bh(&conn->psq_lock); if (psq_empty) @@ -826,15 +838,31 @@ void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid) return; spin_lock_bh(&conn->psq_lock); - skb = skb_dequeue(&conn->psq); - spin_unlock_bh(&conn->psq_lock); + if (conn->mgmt_psq_len > 0) { + mgmt_buf = list_first_entry(&conn->mgmt_psq, + struct ath6kl_mgmt_buff, list); + list_del(&mgmt_buf->list); + conn->mgmt_psq_len--; + spin_unlock_bh(&conn->psq_lock); + + conn->sta_flags |= STA_PS_POLLED; + ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, + mgmt_buf->id, mgmt_buf->freq, + mgmt_buf->wait, mgmt_buf->buf, + mgmt_buf->len, mgmt_buf->no_cck); + conn->sta_flags &= ~STA_PS_POLLED; + kfree(mgmt_buf); + } else { + skb = skb_dequeue(&conn->psq); + spin_unlock_bh(&conn->psq_lock); - conn->sta_flags |= STA_PS_POLLED; - ath6kl_data_tx(skb, vif->ndev); - conn->sta_flags &= ~STA_PS_POLLED; + conn->sta_flags |= STA_PS_POLLED; + ath6kl_data_tx(skb, vif->ndev); + conn->sta_flags &= ~STA_PS_POLLED; + } spin_lock_bh(&conn->psq_lock); - psq_empty = skb_queue_empty(&conn->psq); + psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0); spin_unlock_bh(&conn->psq_lock); if (psq_empty) @@ -920,10 +948,10 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, } ath6kl_cfg80211_disconnect_event(vif, reason, bssid, - assoc_resp_len, assoc_info, - prot_reason_status); + assoc_resp_len, assoc_info, + prot_reason_status); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(vif->aggr_cntxt->aggr_conn); del_timer(&vif->disconnect_timer); @@ -941,9 +969,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, } else { set_bit(CONNECT_PEND, &vif->flags); if (((reason == ASSOC_FAILED) && - (prot_reason_status == 0x11)) || - ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) - && (vif->reconnect_flag == 1))) { + (prot_reason_status == 0x11)) || + ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) && + (vif->reconnect_flag == 1))) { set_bit(CONNECTED, &vif->flags); return; } @@ -1020,11 +1048,155 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev) return &vif->net_stats; } -static struct net_device_ops ath6kl_netdev_ops = { +static int ath6kl_set_features(struct net_device *dev, + netdev_features_t features) +{ + struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = vif->ar; + int err = 0; + + if ((features & NETIF_F_RXCSUM) && + (ar->rx_meta_ver != WMI_META_VERSION_2)) { + ar->rx_meta_ver = WMI_META_VERSION_2; + err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, + vif->fw_vif_idx, + ar->rx_meta_ver, 0, 0); + if (err) { + dev->features = features & ~NETIF_F_RXCSUM; + return err; + } + } else if (!(features & NETIF_F_RXCSUM) && + (ar->rx_meta_ver == WMI_META_VERSION_2)) { + ar->rx_meta_ver = 0; + err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, + vif->fw_vif_idx, + ar->rx_meta_ver, 0, 0); + if (err) { + dev->features = features | NETIF_F_RXCSUM; + return err; + } + + } + + return err; +} + +static void ath6kl_set_multicast_list(struct net_device *ndev) +{ + struct ath6kl_vif *vif = netdev_priv(ndev); + bool mc_all_on = false, mc_all_off = false; + int mc_count = netdev_mc_count(ndev); + struct netdev_hw_addr *ha; + bool found; + struct ath6kl_mc_filter *mc_filter, *tmp; + struct list_head mc_filter_new; + int ret; + + if (!test_bit(WMI_READY, &vif->ar->flag) || + !test_bit(WLAN_ENABLED, &vif->flags)) + return; + + mc_all_on = !!(ndev->flags & IFF_PROMISC) || + !!(ndev->flags & IFF_ALLMULTI) || + !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); + + mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0; + + if (mc_all_on || mc_all_off) { + /* Enable/disable all multicast */ + ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", + mc_all_on ? "enabling" : "disabling"); + ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, + mc_all_on); + if (ret) + ath6kl_warn("Failed to %s multicast receive\n", + mc_all_on ? "enable" : "disable"); + return; + } + + list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { + found = false; + netdev_for_each_mc_addr(ha, ndev) { + if (memcmp(ha->addr, mc_filter->hw_addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + found = true; + break; + } + } + + if (!found) { + /* + * Delete the filter which was previously set + * but not in the new request. + */ + ath6kl_dbg(ATH6KL_DBG_TRC, + "Removing %pM from multicast filter\n", + mc_filter->hw_addr); + ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi, + vif->fw_vif_idx, mc_filter->hw_addr, + false); + if (ret) { + ath6kl_warn("Failed to remove multicast filter:%pM\n", + mc_filter->hw_addr); + return; + } + + list_del(&mc_filter->list); + kfree(mc_filter); + } + } + + INIT_LIST_HEAD(&mc_filter_new); + + netdev_for_each_mc_addr(ha, ndev) { + found = false; + list_for_each_entry(mc_filter, &vif->mc_filter, list) { + if (memcmp(ha->addr, mc_filter->hw_addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + found = true; + break; + } + } + + if (!found) { + mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter), + GFP_ATOMIC); + if (!mc_filter) { + WARN_ON(1); + goto out; + } + + memcpy(mc_filter->hw_addr, ha->addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE); + /* Set the multicast filter */ + ath6kl_dbg(ATH6KL_DBG_TRC, + "Adding %pM to multicast filter list\n", + mc_filter->hw_addr); + ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi, + vif->fw_vif_idx, mc_filter->hw_addr, + true); + if (ret) { + ath6kl_warn("Failed to add multicast filter :%pM\n", + mc_filter->hw_addr); + kfree(mc_filter); + goto out; + } + + list_add_tail(&mc_filter->list, &mc_filter_new); + } + } + +out: + list_splice_tail(&mc_filter_new, &vif->mc_filter); +} + +static const struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, .ndo_get_stats = ath6kl_get_stats, + .ndo_set_features = ath6kl_set_features, + .ndo_set_rx_mode = ath6kl_set_multicast_list, }; void init_netdev(struct net_device *dev) @@ -1038,5 +1210,7 @@ void init_netdev(struct net_device *dev) sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES; + dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + return; } diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 9475e2d0d0b..53528648b42 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,6 +32,7 @@ struct ath6kl_sdio { struct sdio_func *func; + /* protects access to bus_req_freeq */ spinlock_t lock; /* free list */ @@ -49,14 +51,20 @@ struct ath6kl_sdio { /* scatter request list head */ struct list_head scat_req; + atomic_t irq_handling; + wait_queue_head_t irq_wq; + + /* protects access to scat_req */ spinlock_t scat_lock; + bool scatter_enabled; bool is_disabled; - atomic_t irq_handling; const struct sdio_device_id *id; struct work_struct wr_async_work; struct list_head wr_asyncq; + + /* protects access to wr_asyncq */ spinlock_t wr_async_lock; }; @@ -402,7 +410,10 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, return -ENOMEM; mutex_lock(&ar_sdio->dma_buffer_mutex); tbuf = ar_sdio->dma_buffer; - memcpy(tbuf, buf, len); + + if (request & HIF_WRITE) + memcpy(tbuf, buf, len); + bounced = true; } else tbuf = buf; @@ -461,7 +472,6 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) ar_sdio = sdio_get_drvdata(func); atomic_set(&ar_sdio->irq_handling, 1); - /* * Release the host during interrups so we can pick it back up when * we process commands. @@ -470,7 +480,10 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); sdio_claim_host(ar_sdio->func); + atomic_set(&ar_sdio->irq_handling, 0); + wake_up(&ar_sdio->irq_wq); + WARN_ON(status && status != -ECANCELED); } @@ -571,6 +584,13 @@ static void ath6kl_sdio_irq_enable(struct ath6kl *ar) sdio_release_host(ar_sdio->func); } +static bool ath6kl_sdio_is_on_irq(struct ath6kl *ar) +{ + struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); + + return !atomic_read(&ar_sdio->irq_handling); +} + static void ath6kl_sdio_irq_disable(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); @@ -578,10 +598,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar) sdio_claim_host(ar_sdio->func); - /* Mask our function IRQ */ - while (atomic_read(&ar_sdio->irq_handling)) { + if (atomic_read(&ar_sdio->irq_handling)) { sdio_release_host(ar_sdio->func); - schedule_timeout(HZ / 10); + + ret = wait_event_interruptible(ar_sdio->irq_wq, + ath6kl_sdio_is_on_irq(ar)); + if (ret) + return; + sdio_claim_host(ar_sdio->func); } @@ -603,6 +627,8 @@ static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar) node = list_first_entry(&ar_sdio->scat_req, struct hif_scatter_req, list); list_del(&node->list); + + node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req); } spin_unlock_bh(&ar_sdio->scat_lock); @@ -635,8 +661,8 @@ static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar, return -EINVAL; ath6kl_dbg(ATH6KL_DBG_SCATTER, - "hif-scatter: total len: %d scatter entries: %d\n", - scat_req->len, scat_req->scat_entries); + "hif-scatter: total len: %d scatter entries: %d\n", + scat_req->len, scat_req->scat_entries); if (request & HIF_SYNCHRONOUS) status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest); @@ -772,7 +798,6 @@ static int ath6kl_sdio_config(struct ath6kl *ar) if (ret) { ath6kl_err("Set sdio block size %d failed: %d)\n", HIF_MBOX_BLOCK_SIZE, ret); - sdio_release_host(func); goto out; } @@ -782,7 +807,7 @@ out: return ret; } -static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; @@ -793,60 +818,104 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags); - if (!(flags & MMC_PM_KEEP_POWER) || - (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) { - /* as host doesn't support keep power we need to cut power */ - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, - NULL); - } + if (!(flags & MMC_PM_WAKE_SDIO_IRQ) || + !(flags & MMC_PM_KEEP_POWER)) + return -EINVAL; ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { - printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n", - ret); + ath6kl_err("set sdio keep pwr flag failed: %d\n", ret); return ret; } - if (!(flags & MMC_PM_WAKE_SDIO_IRQ)) - goto deepsleep; - /* sdio irq wakes up host */ + ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + if (ret) + ath6kl_err("set sdio wake irq flag failed: %d\n", ret); + + return ret; +} + +static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +{ + struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); + struct sdio_func *func = ar_sdio->func; + mmc_pm_flag_t flags; + bool try_deepsleep = false; + int ret; if (ar->state == ATH6KL_STATE_SCHED_SCAN) { + ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n"); + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_SCHED_SCAN, NULL); - if (ret) { - ath6kl_warn("Schedule scan suspend failed: %d", ret); - return ret; - } + if (ret) + goto cut_pwr; + + return 0; + } + + if (ar->suspend_mode == WLAN_POWER_STATE_WOW || + (!ar->suspend_mode && wow)) { - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + ret = ath6kl_set_sdio_pm_caps(ar); if (ret) - ath6kl_warn("set sdio wake irq flag failed: %d\n", ret); + goto cut_pwr; - return ret; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); + if (ret && ret != -ENOTCONN) + ath6kl_err("wow suspend failed: %d\n", ret); + + if (ret && + (!ar->wow_suspend_mode || + ar->wow_suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP)) + try_deepsleep = true; + else if (ret && + ar->wow_suspend_mode == WLAN_POWER_STATE_CUT_PWR) + goto cut_pwr; + if (!ret) + return 0; } - if (wow) { + if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP || + !ar->suspend_mode || try_deepsleep) { + + flags = sdio_get_host_pm_caps(func); + if (!(flags & MMC_PM_KEEP_POWER)) + goto cut_pwr; + + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (ret) + goto cut_pwr; + /* - * The host sdio controller is capable of keep power and - * sdio irq wake up at this point. It's fine to continue - * wow suspend operation. + * Workaround to support Deep Sleep with MSM, set the host pm + * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable + * the sdc2_clock and internally allows MSM to enter + * TCXO shutdown properly. */ - ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); - if (ret) - return ret; + if ((flags & MMC_PM_WAKE_SDIO_IRQ)) { + ret = sdio_set_host_pm_flags(func, + MMC_PM_WAKE_SDIO_IRQ); + if (ret) + goto cut_pwr; + } - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, + NULL); if (ret) - ath6kl_err("set sdio wake irq flag failed: %d\n", ret); + goto cut_pwr; - return ret; + return 0; } -deepsleep: - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); +cut_pwr: + return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); } static int ath6kl_sdio_resume(struct ath6kl *ar) @@ -869,8 +938,15 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) case ATH6KL_STATE_WOW: break; + case ATH6KL_STATE_SCHED_SCAN: break; + + case ATH6KL_STATE_SUSPENDING: + break; + + case ATH6KL_STATE_RESUMING: + break; } ath6kl_cfg80211_resume(ar); @@ -949,7 +1025,7 @@ static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data) (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC); if (status) { ath6kl_err("%s: failed to read from window data addr\n", - __func__); + __func__); return status; } @@ -1260,10 +1336,12 @@ static int ath6kl_sdio_probe(struct sdio_func *func, INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work); + init_waitqueue_head(&ar_sdio->irq_wq); + for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); - ar = ath6kl_core_alloc(&ar_sdio->func->dev); + ar = ath6kl_core_create(&ar_sdio->func->dev); if (!ar) { ath6kl_err("Failed to alloc ath6kl core\n"); ret = -ENOMEM; @@ -1293,7 +1371,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, return ret; err_core_alloc: - ath6kl_core_free(ar_sdio->ar); + ath6kl_core_destroy(ar_sdio->ar); err_dma: kfree(ar_sdio->dma_buffer); err_hif: @@ -1316,6 +1394,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func) cancel_work_sync(&ar_sdio->wr_async_work); ath6kl_core_cleanup(ar_sdio->ar); + ath6kl_core_destroy(ar_sdio->ar); kfree(ar_sdio->dma_buffer); kfree(ar_sdio); @@ -1332,7 +1411,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); static struct sdio_driver ath6kl_sdio_driver = { - .name = "ath6kl", + .name = "ath6kl_sdio", .id_table = ath6kl_sdio_devices, .probe = ath6kl_sdio_probe, .remove = ath6kl_sdio_remove, @@ -1362,19 +1441,19 @@ MODULE_AUTHOR("Atheros Communications, Inc."); MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE); -MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE); MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE); MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h index 108a723a108..78e0ef4567a 100644 --- a/drivers/net/wireless/ath/ath6kl/target.h +++ b/drivers/net/wireless/ath/ath6kl/target.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2010 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,6 +20,7 @@ #define AR6003_BOARD_DATA_SZ 1024 #define AR6003_BOARD_EXT_DATA_SZ 768 +#define AR6003_BOARD_EXT_DATA_SZ_V2 1024 #define AR6004_BOARD_DATA_SZ 6144 #define AR6004_BOARD_EXT_DATA_SZ 0 diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index 381eb66a605..6675c92b542 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -15,6 +16,7 @@ */ #include "testmode.h" +#include "debug.h" #include <net/netlink.h> @@ -30,7 +32,7 @@ enum ath6kl_tm_attr { enum ath6kl_tm_cmd { ATH6KL_TM_CMD_TCMD = 0, - ATH6KL_TM_CMD_RX_REPORT = 1, + ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */ }; #define ATH6KL_TM_DATA_MAX_LEN 5000 @@ -41,84 +43,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = { .len = ATH6KL_TM_DATA_MAX_LEN }, }; -void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len) +void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len) { - if (down_interruptible(&ar->sem)) - return; - - kfree(ar->tm.rx_report); - - ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL); - ar->tm.rx_report_len = buf_len; - - up(&ar->sem); - - wake_up(&ar->event_wq); -} - -static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len, - struct sk_buff *skb) -{ - int ret = 0; - long left; - - if (down_interruptible(&ar->sem)) - return -ERESTARTSYS; - - if (!test_bit(WMI_READY, &ar->flag)) { - ret = -EIO; - goto out; - } - - if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { - ret = -EBUSY; - goto out; - } - - if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) { - up(&ar->sem); - return -EIO; - } - - left = wait_event_interruptible_timeout(ar->event_wq, - ar->tm.rx_report != NULL, - WMI_TIMEOUT); + struct sk_buff *skb; - if (left == 0) { - ret = -ETIMEDOUT; - goto out; - } else if (left < 0) { - ret = left; - goto out; - } + if (!buf || buf_len == 0) + return; - if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) { - ret = -EINVAL; - goto out; + skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL); + if (!skb) { + ath6kl_warn("failed to allocate testmode rx skb!\n"); + return; } - - NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len, - ar->tm.rx_report); - - kfree(ar->tm.rx_report); - ar->tm.rx_report = NULL; - -out: - up(&ar->sem); - - return ret; + NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD); + NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf); + cfg80211_testmode_event(skb, GFP_KERNEL); + return; nla_put_failure: - ret = -ENOBUFS; - goto out; + kfree_skb(skb); + ath6kl_warn("nla_put failed on testmode rx skb!\n"); } int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) { struct ath6kl *ar = wiphy_priv(wiphy); struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; - int err, buf_len, reply_len; - struct sk_buff *skb; + int err, buf_len; void *buf; err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, @@ -143,24 +94,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) break; case ATH6KL_TM_CMD_RX_REPORT: - if (!tb[ATH6KL_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); - buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); - - reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN); - skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len); - if (!skb) - return -ENOMEM; - - err = ath6kl_tm_rx_report(ar, buf, buf_len, skb); - if (err < 0) { - kfree_skb(skb); - return err; - } - - return cfg80211_testmode_reply(skb); default: return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index 43dffcc11fb..fe651d6707d 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,13 +19,13 @@ #ifdef CONFIG_NL80211_TESTMODE -void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len); +void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len); int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); #else -static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, - size_t buf_len) +static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, + size_t buf_len) { } diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 506a3031a88..f85353fd179 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,6 +18,23 @@ #include "core.h" #include "debug.h" +/* + * tid - tid_mux0..tid_mux3 + * aid - tid_mux4..tid_mux7 + */ +#define ATH6KL_TID_MASK 0xf +#define ATH6KL_AID_SHIFT 4 + +static inline u8 ath6kl_get_tid(u8 tid_mux) +{ + return tid_mux & ATH6KL_TID_MASK; +} + +static inline u8 ath6kl_get_aid(u8 tid_mux) +{ + return tid_mux >> ATH6KL_AID_SHIFT; +} + static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *map_no) { @@ -77,12 +95,118 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, return ar->node_map[ep_map].ep_id; } +static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, + struct ath6kl_vif *vif, + struct sk_buff *skb, + u32 *flags) +{ + struct ath6kl *ar = vif->ar; + bool is_apsdq_empty = false; + struct ethhdr *datap = (struct ethhdr *) skb->data; + u8 up = 0, traffic_class, *ip_hdr; + u16 ether_type; + struct ath6kl_llc_snap_hdr *llc_hdr; + + if (conn->sta_flags & STA_PS_APSD_TRIGGER) { + /* + * This tx is because of a uAPSD trigger, determine + * more and EOSP bit. Set EOSP if queue is empty + * or sufficient frames are delivered for this trigger. + */ + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->apsdq)) + *flags |= WMI_DATA_HDR_FLAGS_MORE; + else if (conn->sta_flags & STA_PS_APSD_EOSP) + *flags |= WMI_DATA_HDR_FLAGS_EOSP; + *flags |= WMI_DATA_HDR_FLAGS_UAPSD; + spin_unlock_bh(&conn->psq_lock); + return false; + } else if (!conn->apsd_info) + return false; + + if (test_bit(WMM_ENABLED, &vif->flags)) { + ether_type = be16_to_cpu(datap->h_proto); + if (is_ethertype(ether_type)) { + /* packet is in DIX format */ + ip_hdr = (u8 *)(datap + 1); + } else { + /* packet is in 802.3 format */ + llc_hdr = (struct ath6kl_llc_snap_hdr *) + (datap + 1); + ether_type = be16_to_cpu(llc_hdr->eth_type); + ip_hdr = (u8 *)(llc_hdr + 1); + } + + if (ether_type == IP_ETHERTYPE) + up = ath6kl_wmi_determine_user_priority( + ip_hdr, 0); + } + + traffic_class = ath6kl_wmi_get_traffic_class(up); + + if ((conn->apsd_info & (1 << traffic_class)) == 0) + return false; + + /* Queue the frames if the STA is sleeping */ + spin_lock_bh(&conn->psq_lock); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + skb_queue_tail(&conn->apsdq, skb); + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this STA + */ + if (is_apsdq_empty) { + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, + vif->fw_vif_idx, + conn->aid, 1, 0); + } + *flags |= WMI_DATA_HDR_FLAGS_UAPSD; + + return true; +} + +static bool ath6kl_process_psq(struct ath6kl_sta *conn, + struct ath6kl_vif *vif, + struct sk_buff *skb, + u32 *flags) +{ + bool is_psq_empty = false; + struct ath6kl *ar = vif->ar; + + if (conn->sta_flags & STA_PS_POLLED) { + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->psq)) + *flags |= WMI_DATA_HDR_FLAGS_MORE; + spin_unlock_bh(&conn->psq_lock); + return false; + } + + /* Queue the frames if the STA is sleeping */ + spin_lock_bh(&conn->psq_lock); + is_psq_empty = skb_queue_empty(&conn->psq); + skb_queue_tail(&conn->psq, skb); + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this + * STA. + */ + if (is_psq_empty) + ath6kl_wmi_set_pvb_cmd(ar->wmi, + vif->fw_vif_idx, + conn->aid, 1); + return true; +} + static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, - bool *more_data) + u32 *flags) { struct ethhdr *datap = (struct ethhdr *) skb->data; struct ath6kl_sta *conn = NULL; - bool ps_queued = false, is_psq_empty = false; + bool ps_queued = false; struct ath6kl *ar = vif->ar; if (is_multicast_ether_addr(datap->h_dest)) { @@ -128,7 +252,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, */ spin_lock_bh(&ar->mcastpsq_lock); if (!skb_queue_empty(&ar->mcastpsq)) - *more_data = true; + *flags |= WMI_DATA_HDR_FLAGS_MORE; spin_unlock_bh(&ar->mcastpsq_lock); } } @@ -142,37 +266,13 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, } if (conn->sta_flags & STA_PS_SLEEP) { - if (!(conn->sta_flags & STA_PS_POLLED)) { - /* Queue the frames if the STA is sleeping */ - spin_lock_bh(&conn->psq_lock); - is_psq_empty = skb_queue_empty(&conn->psq); - skb_queue_tail(&conn->psq, skb); - spin_unlock_bh(&conn->psq_lock); - - /* - * If this is the first pkt getting queued - * for this STA, update the PVB for this - * STA. - */ - if (is_psq_empty) - ath6kl_wmi_set_pvb_cmd(ar->wmi, - vif->fw_vif_idx, - conn->aid, 1); - - ps_queued = true; - } else { - /* - * This tx is because of a PsPoll. - * Determine if MoreData bit has to be set. - */ - spin_lock_bh(&conn->psq_lock); - if (!skb_queue_empty(&conn->psq)) - *more_data = true; - spin_unlock_bh(&conn->psq_lock); - } + ps_queued = ath6kl_process_uapsdq(conn, + vif, skb, flags); + if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD)) + ps_queued = ath6kl_process_psq(conn, + vif, skb, flags); } } - return ps_queued; } @@ -185,6 +285,9 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, int status = 0; struct ath6kl_cookie *cookie = NULL; + if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) + return -EACCES; + spin_lock_bh(&ar->lock); ath6kl_dbg(ATH6KL_DBG_WLAN_TX, @@ -242,8 +345,13 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) u32 map_no = 0; u16 htc_tag = ATH6KL_DATA_PKT_TAG; u8 ac = 99 ; /* initialize to unmapped ac */ - bool chk_adhoc_ps_mapping = false, more_data = false; + bool chk_adhoc_ps_mapping = false; int ret; + struct wmi_tx_meta_v2 meta_v2; + void *meta; + u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed; + u8 meta_ver = 0; + u32 flags = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_TX, "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__, @@ -255,16 +363,29 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) return 0; } + if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { + dev_kfree_skb(skb); + return 0; + } + if (!test_bit(WMI_READY, &ar->flag)) goto fail_tx; /* AP mode Power saving processing */ if (vif->nw_type == AP_NETWORK) { - if (ath6kl_powersave_ap(vif, skb, &more_data)) + if (ath6kl_powersave_ap(vif, skb, &flags)) return 0; } if (test_bit(WMI_ENABLED, &ar->flag)) { + if ((dev->features & NETIF_F_IP_CSUM) && + (csum == CHECKSUM_PARTIAL)) { + csum_start = skb->csum_start - + (skb_network_header(skb) - skb->head) + + sizeof(struct ath6kl_llc_snap_hdr); + csum_dest = skb->csum_offset + csum_start; + } + if (skb_headroom(skb) < dev->needed_headroom) { struct sk_buff *tmp_skb = skb; @@ -281,15 +402,33 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) goto fail_tx; } - if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE, - more_data, 0, 0, NULL, - vif->fw_vif_idx)) { - ath6kl_err("wmi_data_hdr_add failed\n"); + if ((dev->features & NETIF_F_IP_CSUM) && + (csum == CHECKSUM_PARTIAL)) { + meta_v2.csum_start = csum_start; + meta_v2.csum_dest = csum_dest; + + /* instruct target to calculate checksum */ + meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD; + meta_ver = WMI_META_VERSION_2; + meta = &meta_v2; + } else { + meta_ver = 0; + meta = NULL; + } + + ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb, + DATA_MSGTYPE, flags, 0, + meta_ver, + meta, vif->fw_vif_idx); + + if (ret) { + ath6kl_warn("failed to add wmi data header:%d\n" + , ret); goto fail_tx; } if ((vif->nw_type == ADHOC_NETWORK) && - ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) + ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags)) chk_adhoc_ps_mapping = true; else { /* get the stream mapping */ @@ -449,9 +588,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, * WMI queue with too many commands the only exception to * this is during testing using endpointping. */ - spin_lock_bh(&ar->lock); set_bit(WMI_CTRL_EP_FULL, &ar->flag); - spin_unlock_bh(&ar->lock); ath6kl_err("wmi ctrl ep is full\n"); return action; } @@ -465,7 +602,8 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, */ if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] < ar->hiac_stream_active_pri && - ar->cookie_count <= MAX_HI_COOKIE_NUM) + ar->cookie_count <= + target->endpoint[endpoint].tx_drop_packet_threshold) /* * Give preference to the highest priority stream by * dropping the packets which overflowed. @@ -479,9 +617,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, action != HTC_SEND_FULL_DROP) { spin_unlock_bh(&ar->list_lock); - spin_lock_bh(&vif->if_lock); set_bit(NETQ_STOPPED, &vif->flags); - spin_unlock_bh(&vif->if_lock); netif_stop_queue(vif->ndev); return action; @@ -710,10 +846,12 @@ static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr) { struct sk_buff *skb = NULL; - if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) - ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); + if (skb_queue_len(&p_aggr->rx_amsdu_freeq) < + (AGGR_NUM_OF_FREE_NETBUFS >> 2)) + ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, + AGGR_NUM_OF_FREE_NETBUFS); - skb = skb_dequeue(&p_aggr->free_q); + skb = skb_dequeue(&p_aggr->rx_amsdu_freeq); return skb; } @@ -748,7 +886,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) if (!IS_ALIGNED((unsigned long) skb->data, 4)) skb->data = PTR_ALIGN(skb->data - 4, 4); set_htc_rxpkt_info(packet, skb, skb->data, - ATH6KL_BUFFER_SIZE, endpoint); + ATH6KL_BUFFER_SIZE, endpoint); list_add_tail(&packet->list, &queue); } @@ -881,7 +1019,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr, dev_kfree_skb(skb); } -static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, +static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, u16 seq_no, u8 order) { struct sk_buff *skb; @@ -890,11 +1028,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 idx, idx_end, seq_end; struct rxtid_stats *stats; - if (!p_aggr) - return; - - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + rxtid = &agg_conn->rx_tid[tid]; + stats = &agg_conn->stat[tid]; idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); @@ -923,7 +1058,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, if (node->skb) { if (node->is_amsdu) - aggr_slice_amsdu(p_aggr, rxtid, node->skb); + aggr_slice_amsdu(agg_conn->aggr_info, rxtid, + node->skb); else skb_queue_tail(&rxtid->q, node->skb); node->skb = NULL; @@ -939,10 +1075,10 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, stats->num_delivered += skb_queue_len(&rxtid->q); while ((skb = skb_dequeue(&rxtid->q))) - ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb); + ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } -static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, +static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, u16 seq_no, bool is_amsdu, struct sk_buff *frame) { @@ -954,18 +1090,18 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, bool is_queued = false; u16 extended_end; - rxtid = &agg_info->rx_tid[tid]; - stats = &agg_info->stat[tid]; + rxtid = &agg_conn->rx_tid[tid]; + stats = &agg_conn->stat[tid]; stats->num_into_aggr++; if (!rxtid->aggr) { if (is_amsdu) { - aggr_slice_amsdu(agg_info, rxtid, frame); + aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame); is_queued = true; stats->num_amsdu++; while ((skb = skb_dequeue(&rxtid->q))) - ath6kl_deliver_frames_to_nw_stack(agg_info->dev, + ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } return is_queued; @@ -985,7 +1121,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, (cur < end || cur > extended_end)) || ((end > extended_end) && (cur > extended_end) && (cur < end))) { - aggr_deque_frms(agg_info, tid, 0, 0); + aggr_deque_frms(agg_conn, tid, 0, 0); if (cur >= rxtid->hold_q_sz - 1) rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); else @@ -1002,7 +1138,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, st = ATH6KL_MAX_SEQ_NO - (rxtid->hold_q_sz - 2 - cur); - aggr_deque_frms(agg_info, tid, st, 0); + aggr_deque_frms(agg_conn, tid, st, 0); } stats->num_oow++; @@ -1041,9 +1177,9 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, spin_unlock_bh(&rxtid->lock); - aggr_deque_frms(agg_info, tid, 0, 1); + aggr_deque_frms(agg_conn, tid, 0, 1); - if (agg_info->timer_scheduled) + if (agg_conn->timer_scheduled) rxtid->progress = true; else for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { @@ -1054,8 +1190,8 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, * the frame doesn't remain stuck * forever. */ - agg_info->timer_scheduled = true; - mod_timer(&agg_info->timer, + agg_conn->timer_scheduled = true; + mod_timer(&agg_conn->timer, (jiffies + HZ * (AGGR_RX_TIMEOUT) / 1000)); rxtid->progress = false; @@ -1067,6 +1203,76 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, return is_queued; } +static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif, + struct ath6kl_sta *conn) +{ + struct ath6kl *ar = vif->ar; + bool is_apsdq_empty, is_apsdq_empty_at_start; + u32 num_frames_to_deliver, flags; + struct sk_buff *skb = NULL; + + /* + * If the APSD q for this STA is not empty, dequeue and + * send a pkt from the head of the q. Also update the + * More data bit in the WMI_DATA_HDR if there are + * more pkts for this STA in the APSD q. + * If there are no more pkts for this STA, + * update the APSD bitmap for this STA. + */ + + num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) & + ATH6KL_APSD_FRAME_MASK; + /* + * Number of frames to send in a service period is + * indicated by the station + * in the QOS_INFO of the association request + * If it is zero, send all frames + */ + if (!num_frames_to_deliver) + num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME; + + spin_lock_bh(&conn->psq_lock); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + spin_unlock_bh(&conn->psq_lock); + is_apsdq_empty_at_start = is_apsdq_empty; + + while ((!is_apsdq_empty) && (num_frames_to_deliver)) { + + spin_lock_bh(&conn->psq_lock); + skb = skb_dequeue(&conn->apsdq); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + spin_unlock_bh(&conn->psq_lock); + + /* + * Set the STA flag to Trigger delivery, + * so that the frame will go out + */ + conn->sta_flags |= STA_PS_APSD_TRIGGER; + num_frames_to_deliver--; + + /* Last frame in the service period, set EOSP or queue empty */ + if ((is_apsdq_empty) || (!num_frames_to_deliver)) + conn->sta_flags |= STA_PS_APSD_EOSP; + + ath6kl_data_tx(skb, vif->ndev); + conn->sta_flags &= ~(STA_PS_APSD_TRIGGER); + conn->sta_flags &= ~(STA_PS_APSD_EOSP); + } + + if (is_apsdq_empty) { + if (is_apsdq_empty_at_start) + flags = WMI_AP_APSD_NO_DELIVERY_FRAMES; + else + flags = 0; + + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, + vif->fw_vif_idx, + conn->aid, 0, flags); + } + + return; +} + void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) { struct ath6kl *ar = target->dev->ar; @@ -1078,10 +1284,12 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) int status = packet->status; enum htc_endpoint_id ept = packet->endpoint; bool is_amsdu, prev_ps, ps_state = false; + bool trig_state = false; struct ath6kl_sta *conn = NULL; struct sk_buff *skb1 = NULL; struct ethhdr *datap = NULL; struct ath6kl_vif *vif; + struct aggr_info_conn *aggr_conn; u16 seq_no, offset; u8 tid, if_idx; @@ -1098,7 +1306,15 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) skb_put(skb, packet->act_len + HTC_HDR_LENGTH); skb_pull(skb, HTC_HDR_LENGTH); + ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ", + skb->data, skb->len); + if (ept == ar->ctrl_ep) { + if (test_bit(WMI_ENABLED, &ar->flag)) { + ath6kl_check_wow_status(ar); + ath6kl_wmi_control_rx(ar->wmi, skb); + return; + } if_idx = wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data); } else { @@ -1123,10 +1339,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) spin_unlock_bh(&vif->if_lock); - - ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ", - skb->data, skb->len); - skb->dev = vif->ndev; if (!test_bit(WMI_ENABLED, &ar->flag)) { @@ -1138,11 +1350,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) ath6kl_check_wow_status(ar); - if (ept == ar->ctrl_ep) { - ath6kl_wmi_control_rx(ar->wmi, skb); - return; - } - min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) + sizeof(struct ath6kl_llc_snap_hdr); @@ -1171,6 +1378,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) WMI_DATA_HDR_PS_MASK); offset = sizeof(struct wmi_data_hdr); + trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG); switch (meta_type) { case 0: @@ -1209,18 +1417,61 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) else conn->sta_flags &= ~STA_PS_SLEEP; + /* Accept trigger only when the station is in sleep */ + if ((conn->sta_flags & STA_PS_SLEEP) && trig_state) + ath6kl_uapsd_trigger_frame_rx(vif, conn); + if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) { if (!(conn->sta_flags & STA_PS_SLEEP)) { struct sk_buff *skbuff = NULL; + bool is_apsdq_empty; + struct ath6kl_mgmt_buff *mgmt; + u8 idx; spin_lock_bh(&conn->psq_lock); - while ((skbuff = skb_dequeue(&conn->psq)) - != NULL) { + while (conn->mgmt_psq_len > 0) { + mgmt = list_first_entry( + &conn->mgmt_psq, + struct ath6kl_mgmt_buff, + list); + list_del(&mgmt->list); + conn->mgmt_psq_len--; + spin_unlock_bh(&conn->psq_lock); + idx = vif->fw_vif_idx; + + ath6kl_wmi_send_mgmt_cmd(ar->wmi, + idx, + mgmt->id, + mgmt->freq, + mgmt->wait, + mgmt->buf, + mgmt->len, + mgmt->no_cck); + + kfree(mgmt); + spin_lock_bh(&conn->psq_lock); + } + conn->mgmt_psq_len = 0; + while ((skbuff = skb_dequeue(&conn->psq))) { + spin_unlock_bh(&conn->psq_lock); + ath6kl_data_tx(skbuff, vif->ndev); + spin_lock_bh(&conn->psq_lock); + } + + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + while ((skbuff = skb_dequeue(&conn->apsdq))) { spin_unlock_bh(&conn->psq_lock); ath6kl_data_tx(skbuff, vif->ndev); spin_lock_bh(&conn->psq_lock); } spin_unlock_bh(&conn->psq_lock); + + if (!is_apsdq_empty) + ath6kl_wmi_set_apsd_bfrd_traf( + ar->wmi, + vif->fw_vif_idx, + conn->aid, 0, 0); + /* Clear the PVB for this STA */ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0); @@ -1314,11 +1565,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) datap = (struct ethhdr *) skb->data; - if (is_unicast_ether_addr(datap->h_dest) && - aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no, - is_amsdu, skb)) - /* aggregation code will handle the skb */ - return; + if (is_unicast_ether_addr(datap->h_dest)) { + if (vif->nw_type == AP_NETWORK) { + conn = ath6kl_find_sta(vif, datap->h_source); + if (!conn) + return; + aggr_conn = conn->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; + + if (aggr_process_recv_frm(aggr_conn, tid, seq_no, + is_amsdu, skb)) { + /* aggregation code will handle the skb */ + return; + } + } ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); } @@ -1326,13 +1587,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) static void aggr_timeout(unsigned long arg) { u8 i, j; - struct aggr_info *p_aggr = (struct aggr_info *) arg; + struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg; struct rxtid *rxtid; struct rxtid_stats *stats; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; - stats = &p_aggr->stat[i]; + rxtid = &aggr_conn->rx_tid[i]; + stats = &aggr_conn->stat[i]; if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) continue; @@ -1343,18 +1604,18 @@ static void aggr_timeout(unsigned long arg) rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO)); - aggr_deque_frms(p_aggr, i, 0, 0); + aggr_deque_frms(aggr_conn, i, 0, 0); } - p_aggr->timer_scheduled = false; + aggr_conn->timer_scheduled = false; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; + rxtid = &aggr_conn->rx_tid[i]; if (rxtid->aggr && rxtid->hold_q) { for (j = 0; j < rxtid->hold_q_sz; j++) { if (rxtid->hold_q[j].skb) { - p_aggr->timer_scheduled = true; + aggr_conn->timer_scheduled = true; rxtid->timer_mon = true; rxtid->progress = false; break; @@ -1366,24 +1627,24 @@ static void aggr_timeout(unsigned long arg) } } - if (p_aggr->timer_scheduled) - mod_timer(&p_aggr->timer, + if (aggr_conn->timer_scheduled) + mod_timer(&aggr_conn->timer, jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT)); } -static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) +static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) { struct rxtid *rxtid; struct rxtid_stats *stats; - if (!p_aggr || tid >= NUM_OF_TIDS) + if (!aggr_conn || tid >= NUM_OF_TIDS) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + rxtid = &aggr_conn->rx_tid[tid]; + stats = &aggr_conn->stat[tid]; if (rxtid->aggr) - aggr_deque_frms(p_aggr, tid, 0, 0); + aggr_deque_frms(aggr_conn, tid, 0, 0); rxtid->aggr = false; rxtid->progress = false; @@ -1398,26 +1659,40 @@ static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) memset(stats, 0, sizeof(struct rxtid_stats)); } -void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, +void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, u8 win_sz) { - struct aggr_info *p_aggr = vif->aggr_cntxt; + struct ath6kl_sta *sta; + struct aggr_info_conn *aggr_conn = NULL; struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; + u8 tid, aid; - if (!p_aggr) + if (vif->nw_type == AP_NETWORK) { + aid = ath6kl_get_aid(tid_mux); + sta = ath6kl_find_sta_by_aid(vif->ar, aid); + if (sta) + aggr_conn = sta->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; + + if (!aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + tid = ath6kl_get_tid(tid_mux); + if (tid >= NUM_OF_TIDS) + return; + + rxtid = &aggr_conn->rx_tid[tid]; + stats = &aggr_conn->stat[tid]; if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n", __func__, win_sz, tid); if (rxtid->aggr) - aggr_delete_tid_state(p_aggr, tid); + aggr_delete_tid_state(aggr_conn, tid); rxtid->seq_next = seq_no; hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q); @@ -1433,31 +1708,23 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, rxtid->aggr = true; } -struct aggr_info *aggr_init(struct net_device *dev) +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, + struct aggr_info_conn *aggr_conn) { - struct aggr_info *p_aggr = NULL; struct rxtid *rxtid; u8 i; - p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); - if (!p_aggr) { - ath6kl_err("failed to alloc memory for aggr_node\n"); - return NULL; - } - - p_aggr->aggr_sz = AGGR_SZ_DEFAULT; - p_aggr->dev = dev; - init_timer(&p_aggr->timer); - p_aggr->timer.function = aggr_timeout; - p_aggr->timer.data = (unsigned long) p_aggr; - - p_aggr->timer_scheduled = false; - skb_queue_head_init(&p_aggr->free_q); + aggr_conn->aggr_sz = AGGR_SZ_DEFAULT; + aggr_conn->dev = vif->ndev; + init_timer(&aggr_conn->timer); + aggr_conn->timer.function = aggr_timeout; + aggr_conn->timer.data = (unsigned long) aggr_conn; + aggr_conn->aggr_info = aggr_info; - ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); + aggr_conn->timer_scheduled = false; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; + rxtid = &aggr_conn->rx_tid[i]; rxtid->aggr = false; rxtid->progress = false; rxtid->timer_mon = false; @@ -1465,29 +1732,75 @@ struct aggr_info *aggr_init(struct net_device *dev) spin_lock_init(&rxtid->lock); } +} + +struct aggr_info *aggr_init(struct ath6kl_vif *vif) +{ + struct aggr_info *p_aggr = NULL; + + p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); + if (!p_aggr) { + ath6kl_err("failed to alloc memory for aggr_node\n"); + return NULL; + } + + p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + if (!p_aggr->aggr_conn) { + ath6kl_err("failed to alloc memory for connection specific aggr info\n"); + kfree(p_aggr); + return NULL; + } + + aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn); + + skb_queue_head_init(&p_aggr->rx_amsdu_freeq); + ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS); + return p_aggr; } -void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) +void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) { - struct aggr_info *p_aggr = vif->aggr_cntxt; + struct ath6kl_sta *sta; struct rxtid *rxtid; + struct aggr_info_conn *aggr_conn = NULL; + u8 tid, aid; + + if (vif->nw_type == AP_NETWORK) { + aid = ath6kl_get_aid(tid_mux); + sta = ath6kl_find_sta_by_aid(vif->ar, aid); + if (sta) + aggr_conn = sta->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; - if (!p_aggr) + if (!aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; + tid = ath6kl_get_tid(tid_mux); + if (tid >= NUM_OF_TIDS) + return; + + rxtid = &aggr_conn->rx_tid[tid]; if (rxtid->aggr) - aggr_delete_tid_state(p_aggr, tid); + aggr_delete_tid_state(aggr_conn, tid); } -void aggr_reset_state(struct aggr_info *aggr_info) +void aggr_reset_state(struct aggr_info_conn *aggr_conn) { u8 tid; + if (!aggr_conn) + return; + + if (aggr_conn->timer_scheduled) { + del_timer(&aggr_conn->timer); + aggr_conn->timer_scheduled = false; + } + for (tid = 0; tid < NUM_OF_TIDS; tid++) - aggr_delete_tid_state(aggr_info, tid); + aggr_delete_tid_state(aggr_conn, tid); } /* clean up our amsdu buffer list */ @@ -1514,28 +1827,11 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar) void aggr_module_destroy(struct aggr_info *aggr_info) { - struct rxtid *rxtid; - u8 i, k; - if (!aggr_info) return; - if (aggr_info->timer_scheduled) { - del_timer(&aggr_info->timer); - aggr_info->timer_scheduled = false; - } - - for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &aggr_info->rx_tid[i]; - if (rxtid->hold_q) { - for (k = 0; k < rxtid->hold_q_sz; k++) - dev_kfree_skb(rxtid->hold_q[k].skb); - kfree(rxtid->hold_q); - } - - skb_queue_purge(&rxtid->q); - } - - skb_queue_purge(&aggr_info->free_q); + aggr_reset_state(aggr_info->aggr_conn); + skb_queue_purge(&aggr_info->rx_amsdu_freeq); + kfree(aggr_info->aggr_conn); kfree(aggr_info); } diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c new file mode 100644 index 00000000000..325b1224c2b --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/module.h> +#include <linux/usb.h> + +#include "debug.h" +#include "core.h" + +/* usb device object */ +struct ath6kl_usb { + struct usb_device *udev; + struct usb_interface *interface; + u8 *diag_cmd_buffer; + u8 *diag_resp_buffer; + struct ath6kl *ar; +}; + +/* diagnostic command defnitions */ +#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1 +#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2 +#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3 +#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4 + +#define ATH6KL_USB_CTRL_DIAG_CC_READ 0 +#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1 + +struct ath6kl_usb_ctrl_diag_cmd_write { + __le32 cmd; + __le32 address; + __le32 value; + __le32 _pad[1]; +} __packed; + +struct ath6kl_usb_ctrl_diag_cmd_read { + __le32 cmd; + __le32 address; +} __packed; + +struct ath6kl_usb_ctrl_diag_resp_read { + __le32 value; +} __packed; + +#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)) +#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read)) + +static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb) +{ + usb_set_intfdata(ar_usb->interface, NULL); + + kfree(ar_usb->diag_cmd_buffer); + kfree(ar_usb->diag_resp_buffer); + + kfree(ar_usb); +} + +static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) +{ + struct ath6kl_usb *ar_usb = NULL; + struct usb_device *dev = interface_to_usbdev(interface); + int status = 0; + + ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); + if (ar_usb == NULL) + goto fail_ath6kl_usb_create; + + memset(ar_usb, 0, sizeof(struct ath6kl_usb)); + usb_set_intfdata(interface, ar_usb); + ar_usb->udev = dev; + ar_usb->interface = interface; + + ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL); + if (ar_usb->diag_cmd_buffer == NULL) { + status = -ENOMEM; + goto fail_ath6kl_usb_create; + } + + ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP, + GFP_KERNEL); + if (ar_usb->diag_resp_buffer == NULL) { + status = -ENOMEM; + goto fail_ath6kl_usb_create; + } + +fail_ath6kl_usb_create: + if (status != 0) { + ath6kl_usb_destroy(ar_usb); + ar_usb = NULL; + } + return ar_usb; +} + +static void ath6kl_usb_device_detached(struct usb_interface *interface) +{ + struct ath6kl_usb *ar_usb; + + ar_usb = usb_get_intfdata(interface); + if (ar_usb == NULL) + return; + + ath6kl_stop_txrx(ar_usb->ar); + + ath6kl_core_cleanup(ar_usb->ar); + + ath6kl_usb_destroy(ar_usb); +} + +static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, + u8 req, u16 value, u16 index, void *data, + u32 size) +{ + u8 *buf = NULL; + int ret; + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + memcpy(buf, data, size); + } + + /* note: if successful returns number of bytes transfered */ + ret = usb_control_msg(ar_usb->udev, + usb_sndctrlpipe(ar_usb->udev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 1000); + + if (ret < 0) { + ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", + __func__, ret); + } + + kfree(buf); + + return 0; +} + +static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, + u8 req, u16 value, u16 index, void *data, + u32 size) +{ + u8 *buf = NULL; + int ret; + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + } + + /* note: if successful returns number of bytes transfered */ + ret = usb_control_msg(ar_usb->udev, + usb_rcvctrlpipe(ar_usb->udev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 2 * HZ); + + if (ret < 0) { + ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", + __func__, ret); + } + + memcpy((u8 *) data, buf, size); + + kfree(buf); + + return 0; +} + +static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb, + u8 req_val, u8 *req_buf, u32 req_len, + u8 resp_val, u8 *resp_buf, u32 *resp_len) +{ + int ret; + + /* send command */ + ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0, + req_buf, req_len); + + if (ret != 0) + return ret; + + if (resp_buf == NULL) { + /* no expected response */ + return ret; + } + + /* get response */ + ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0, + resp_buf, *resp_len); + + return ret; +} + +static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + struct ath6kl_usb_ctrl_diag_resp_read *resp; + struct ath6kl_usb_ctrl_diag_cmd_read *cmd; + u32 resp_len; + int ret; + + cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer; + + memset(cmd, 0, sizeof(*cmd)); + cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ; + cmd->address = cpu_to_le32(address); + resp_len = sizeof(*resp); + + ret = ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(struct ath6kl_usb_ctrl_diag_cmd_write), + ATH6KL_USB_CONTROL_REQ_DIAG_RESP, + ar_usb->diag_resp_buffer, &resp_len); + + if (ret) + return ret; + + resp = (struct ath6kl_usb_ctrl_diag_resp_read *) + ar_usb->diag_resp_buffer; + + *data = le32_to_cpu(resp->value); + + return ret; +} + +static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + struct ath6kl_usb_ctrl_diag_cmd_write *cmd; + + cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; + + memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)); + cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE); + cmd->address = cpu_to_le32(address); + cmd->value = data; + + return ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(*cmd), + 0, NULL, NULL); + +} + +static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + int ret; + + /* get response */ + ret = ath6kl_usb_submit_ctrl_in(ar_usb, + ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, + 0, 0, buf, len); + if (ret != 0) { + ath6kl_err("Unable to read the bmi data from the device: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + int ret; + + /* send command */ + ret = ath6kl_usb_submit_ctrl_out(ar_usb, + ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, + 0, 0, buf, len); + if (ret != 0) { + ath6kl_err("unable to send the bmi data to the device: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ath6kl_usb_power_on(struct ath6kl *ar) +{ + return 0; +} + +static int ath6kl_usb_power_off(struct ath6kl *ar) +{ + return 0; +} + +static const struct ath6kl_hif_ops ath6kl_usb_ops = { + .diag_read32 = ath6kl_usb_diag_read32, + .diag_write32 = ath6kl_usb_diag_write32, + .bmi_read = ath6kl_usb_bmi_read, + .bmi_write = ath6kl_usb_bmi_write, + .power_on = ath6kl_usb_power_on, + .power_off = ath6kl_usb_power_off, +}; + +/* ath6kl usb driver registered functions */ +static int ath6kl_usb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(interface); + struct ath6kl *ar; + struct ath6kl_usb *ar_usb = NULL; + int vendor_id, product_id; + int ret = 0; + + usb_get_dev(dev); + + vendor_id = le16_to_cpu(dev->descriptor.idVendor); + product_id = le16_to_cpu(dev->descriptor.idProduct); + + ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id); + ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id); + + if (interface->cur_altsetting) + ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n", + interface->cur_altsetting->desc.bInterfaceNumber); + + + if (dev->speed == USB_SPEED_HIGH) + ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n"); + else + ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n"); + + ar_usb = ath6kl_usb_create(interface); + + if (ar_usb == NULL) { + ret = -ENOMEM; + goto err_usb_put; + } + + ar = ath6kl_core_create(&ar_usb->udev->dev); + if (ar == NULL) { + ath6kl_err("Failed to alloc ath6kl core\n"); + ret = -ENOMEM; + goto err_usb_destroy; + } + + ar->hif_priv = ar_usb; + ar->hif_type = ATH6KL_HIF_TYPE_USB; + ar->hif_ops = &ath6kl_usb_ops; + ar->mbox_info.block_size = 16; + ar->bmi.max_data_size = 252; + + ar_usb->ar = ar; + + ret = ath6kl_core_init(ar); + if (ret) { + ath6kl_err("Failed to init ath6kl core: %d\n", ret); + goto err_core_free; + } + + return ret; + +err_core_free: + ath6kl_core_destroy(ar); +err_usb_destroy: + ath6kl_usb_destroy(ar_usb); +err_usb_put: + usb_put_dev(dev); + + return ret; +} + +static void ath6kl_usb_remove(struct usb_interface *interface) +{ + usb_put_dev(interface_to_usbdev(interface)); + ath6kl_usb_device_detached(interface); +} + +/* table of devices that work with this driver */ +static struct usb_device_id ath6kl_usb_ids[] = { + {USB_DEVICE(0x0cf3, 0x9374)}, + { /* Terminating entry */ }, +}; + +MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids); + +static struct usb_driver ath6kl_usb_driver = { + .name = "ath6kl_usb", + .probe = ath6kl_usb_probe, + .disconnect = ath6kl_usb_remove, + .id_table = ath6kl_usb_ids, +}; + +static int ath6kl_usb_init(void) +{ + usb_register(&ath6kl_usb_driver); + return 0; +} + +static void ath6kl_usb_exit(void) +{ + usb_deregister(&ath6kl_usb_driver); +} + +module_init(ath6kl_usb_init); +module_exit(ath6kl_usb_exit); + +MODULE_AUTHOR("Atheros Communications, Inc."); +MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index f6f2aa27fc2..2b442332cd0 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -126,7 +127,7 @@ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb) if (!is_ethertype(be16_to_cpu(type))) { ath6kl_dbg(ATH6KL_DBG_WMI, - "%s: pkt is already in 802.3 format\n", __func__); + "%s: pkt is already in 802.3 format\n", __func__); return 0; } @@ -180,7 +181,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb, } int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, - u8 msg_type, bool more_data, + u8 msg_type, u32 flags, enum wmi_data_hdr_data_type data_type, u8 meta_ver, void *tx_meta_info, u8 if_idx) { @@ -204,17 +205,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT; data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT; - if (more_data) - data_hdr->info |= - WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT; + if (flags & WMI_DATA_HDR_FLAGS_MORE) + data_hdr->info |= WMI_DATA_HDR_MORE; - data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); - data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); + if (flags & WMI_DATA_HDR_FLAGS_EOSP) + data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP); + + data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); + data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); return 0; } -static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) +u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) { struct iphdr *ip_hdr = (struct iphdr *) pkt; u8 ip_pri; @@ -236,6 +239,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) return ip_pri; } +u8 ath6kl_wmi_get_traffic_class(u8 user_priority) +{ + return up_to_ac[user_priority & 0x7]; +} + int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, u32 layer2_priority, bool wmm_enabled, @@ -419,9 +427,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len) ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n", evt->num_msg, evt->msg_len, evt->msg_type); - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI)) - return 0; - for (index = 0; index < evt->num_msg; index++) { size = sizeof(struct wmi_tx_complete_event) + (index * sizeof(struct tx_complete_msg_v1)); @@ -552,7 +557,8 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, dlen, freq, vif->probe_req_report); if (vif->probe_req_report || vif->nw_type == AP_NETWORK) - cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(vif->ndev, freq, 0, + ev->data, dlen, GFP_ATOMIC); return 0; } @@ -591,7 +597,8 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, return -EINVAL; } ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); - cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(vif->ndev, freq, 0, + ev->data, dlen, GFP_ATOMIC); return 0; } @@ -786,12 +793,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, ev->u.ap_sta.keymgmt, le16_to_cpu(ev->u.ap_sta.cipher), ev->u.ap_sta.apsd_info); + ath6kl_connect_ap_mode_sta( vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, ev->u.ap_sta.keymgmt, le16_to_cpu(ev->u.ap_sta.cipher), ev->u.ap_sta.auth, ev->assoc_req_len, - ev->assoc_info + ev->beacon_ie_len); + ev->assoc_info + ev->beacon_ie_len, + ev->u.ap_sta.apsd_info); } return 0; } @@ -819,8 +828,8 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 && pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) { /* WMM OUT (00:50:F2) */ - if (pie[1] > 5 - && pie[6] == WMM_PARAM_OUI_SUBTYPE) + if (pie[1] > 5 && + pie[6] == WMM_PARAM_OUI_SUBTYPE) wmi->is_wmm_enabled = true; } break; @@ -904,17 +913,17 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) regpair = ath6kl_get_regpair((u16) reg_code); country = ath6kl_regd_find_country_by_rd((u16) reg_code); ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", - regpair->regDmnEnum); + regpair->regDmnEnum); } - if (country) { + if (country && wmi->parent_dev->wiphy_registered) { alpha2[0] = country->isoName[0]; alpha2[1] = country->isoName[1]; regulatory_hint(wmi->parent_dev->wiphy, alpha2); ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n", - alpha2[0], alpha2[1]); + alpha2[0], alpha2[1]); } } @@ -1025,8 +1034,9 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, if (len < 8 + 2 + 2) return -EINVAL; - if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags) - && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { + if (bih->frame_type == BEACON_FTYPE && + test_bit(CONNECTED, &vif->flags) && + memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) { const u8 *tim; tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2, len - 8 - 2 - 2); @@ -1145,9 +1155,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) return 0; } -static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len) +static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len) { - ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len); + ath6kl_tm_rx_event(wmi->parent_dev, datap, len); return 0; } @@ -1358,8 +1368,8 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Upper threshold breached */ if (rssi < sq_thresh->upper_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious upper rssi threshold event: %d\n", - rssi); + "spurious upper rssi threshold event: %d\n", + rssi); } else if ((rssi < sq_thresh->upper_threshold[1]) && (rssi >= sq_thresh->upper_threshold[0])) { new_threshold = WMI_RSSI_THRESHOLD1_ABOVE; @@ -1382,7 +1392,7 @@ static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Lower threshold breached */ if (rssi > sq_thresh->lower_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious lower rssi threshold event: %d %d\n", + "spurious lower rssi threshold event: %d %d\n", rssi, sq_thresh->lower_threshold[0]); } else if ((rssi > sq_thresh->lower_threshold[1]) && (rssi <= sq_thresh->lower_threshold[0])) { @@ -1543,8 +1553,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Upper threshold breached */ if (snr < sq_thresh->upper_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious upper snr threshold event: %d\n", - snr); + "spurious upper snr threshold event: %d\n", + snr); } else if ((snr < sq_thresh->upper_threshold[1]) && (snr >= sq_thresh->upper_threshold[0])) { new_threshold = WMI_SNR_THRESHOLD1_ABOVE; @@ -1561,8 +1571,8 @@ static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap, /* Lower threshold breached */ if (snr > sq_thresh->lower_threshold[0]) { ath6kl_dbg(ATH6KL_DBG_WMI, - "spurious lower snr threshold event: %d\n", - sq_thresh->lower_threshold[0]); + "spurious lower snr threshold event: %d\n", + sq_thresh->lower_threshold[0]); } else if ((snr > sq_thresh->lower_threshold[1]) && (snr <= sq_thresh->lower_threshold[0])) { new_threshold = WMI_SNR_THRESHOLD4_BELOW; @@ -2020,6 +2030,26 @@ int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, return ret; } +int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx, + u16 bmiss_time, u16 num_beacons) +{ + struct sk_buff *skb; + struct wmi_bmiss_time_cmd *cmd; + int ret; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_bmiss_time_cmd *) skb->data; + cmd->bmiss_time = cpu_to_le16(bmiss_time); + cmd->num_beacons = cpu_to_le16(num_beacons); + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BMISS_TIME_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} + int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode) { struct sk_buff *skb; @@ -2479,15 +2509,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class, return ret; } -int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) +int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, + __be32 ips0, __be32 ips1) { struct sk_buff *skb; struct wmi_set_ip_cmd *cmd; int ret; /* Multicast address are not valid */ - if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) || - (*((u8 *) &ip_cmd->ips[1]) >= 0xE0)) + if (ipv4_is_multicast(ips0) || + ipv4_is_multicast(ips1)) return -EINVAL; skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd)); @@ -2495,9 +2526,10 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) return -ENOMEM; cmd = (struct wmi_set_ip_cmd *) skb->data; - memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd)); + cmd->ips[0] = ips0; + cmd->ips[1] = ips1; - ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG); return ret; } @@ -2582,6 +2614,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, return ret; } +/* This command has zero length payload */ +static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi, + struct ath6kl_vif *vif) +{ + struct ath6kl *ar = wmi->parent_dev; + + set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); + wake_up(&ar->event_wq); + + return 0; +} + int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_wow_mode wow_mode, u32 filter, u16 host_req_delay) @@ -2591,7 +2635,7 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, int ret; if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) && - wow_mode != ATH6KL_WOW_MODE_DISABLE) { + wow_mode != ATH6KL_WOW_MODE_DISABLE) { ath6kl_err("invalid wow mode: %d\n", wow_mode); return -EINVAL; } @@ -2612,7 +2656,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask) + u8 filter_offset, const u8 *filter, + const u8 *mask) { struct sk_buff *skb; struct wmi_add_wow_pattern_cmd *cmd; @@ -2853,6 +2898,51 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len) return ret; } +int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on) +{ + struct sk_buff *skb; + struct wmi_mcast_filter_cmd *cmd; + int ret; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_mcast_filter_cmd *) skb->data; + cmd->mcast_all_enable = mc_all_on; + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} + +int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, + u8 *filter, bool add_filter) +{ + struct sk_buff *skb; + struct wmi_mcast_filter_add_del_cmd *cmd; + int ret; + + if ((filter[0] != 0x33 || filter[1] != 0x33) && + (filter[0] != 0x01 || filter[1] != 0x00 || + filter[2] != 0x5e || filter[3] > 0x7f)) { + ath6kl_warn("invalid multicast filter address\n"); + return -EINVAL; + } + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data; + memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE); + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, + add_filter ? WMI_SET_MCAST_FILTER_CMDID : + WMI_DEL_MCAST_FILTER_CMDID, + NO_SYNC_WMIFLAG); + + return ret; +} s32 ath6kl_wmi_get_rate(s8 rate_index) { @@ -2946,6 +3036,59 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, NO_SYNC_WMIFLAG); } +int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable) +{ + struct sk_buff *skb; + struct wmi_ap_hidden_ssid_cmd *cmd; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_hidden_ssid_cmd *) skb->data; + cmd->hidden_ssid = enable ? 1 : 0; + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_HIDDEN_SSID_CMDID, + NO_SYNC_WMIFLAG); +} + +/* This command will be used to enable/disable AP uAPSD feature */ +int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) +{ + struct wmi_ap_set_apsd_cmd *cmd; + struct sk_buff *skb; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_set_apsd_cmd *)skb->data; + cmd->enable = enable; + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID, + NO_SYNC_WMIFLAG); +} + +int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx, + u16 aid, u16 bitmap, u32 flags) +{ + struct wmi_ap_apsd_buffered_traffic_cmd *cmd; + struct sk_buff *skb; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data; + cmd->aid = cpu_to_le16(aid); + cmd->bitmap = cpu_to_le16(bitmap); + cmd->flags = cpu_to_le32(flags); + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID, + NO_SYNC_WMIFLAG); +} + static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, struct ath6kl_vif *vif) { @@ -3078,8 +3221,9 @@ int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur) * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P * mgmt operations using station interface. */ -int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, - u32 wait, const u8 *data, u16 data_len) +static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, + u32 freq, u32 wait, const u8 *data, + u16 data_len) { struct sk_buff *skb; struct wmi_send_action_cmd *p; @@ -3115,9 +3259,9 @@ int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, NO_SYNC_WMIFLAG); } -int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, - u32 wait, const u8 *data, u16 data_len, - u32 no_cck) +static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, + u32 freq, u32 wait, const u8 *data, + u16 data_len, u32 no_cck) { struct sk_buff *skb; struct wmi_send_mgmt_cmd *p; @@ -3154,6 +3298,32 @@ int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, NO_SYNC_WMIFLAG); } +int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, + u32 wait, const u8 *data, u16 data_len, + u32 no_cck) +{ + int status; + struct ath6kl *ar = wmi->parent_dev; + + if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, + ar->fw_capabilities)) { + /* + * If capable of doing P2P mgmt operations using + * station interface, send additional information like + * supported rates to advertise and xmit rates for + * probe requests + */ + status = __ath6kl_wmi_send_mgmt_cmd(ar->wmi, if_idx, id, freq, + wait, data, data_len, + no_cck); + } else { + status = ath6kl_wmi_send_action_cmd(ar->wmi, if_idx, id, freq, + wait, data, data_len); + } + + return status; +} + int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq, const u8 *dst, const u8 *data, u16 data_len) @@ -3265,32 +3435,101 @@ static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len) return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len); } -/* Control Path */ -int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) +/* Process interface specific wmi events, caller would free the datap */ +static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, + u8 *datap, u32 len) { - struct wmi_cmd_hdr *cmd; struct ath6kl_vif *vif; - u32 len; - u16 id; - u8 if_idx; - u8 *datap; - int ret = 0; - if (WARN_ON(skb == NULL)) + vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx); + if (!vif) { + ath6kl_dbg(ATH6KL_DBG_WMI, + "Wmi event for unavailable vif, vif_index:%d\n", + if_idx); return -EINVAL; + } - if (skb->len < sizeof(struct wmi_cmd_hdr)) { - ath6kl_err("bad packet 1\n"); - dev_kfree_skb(skb); + switch (cmd_id) { + case WMI_CONNECT_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n"); + return ath6kl_wmi_connect_event_rx(wmi, datap, len, vif); + case WMI_DISCONNECT_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); + return ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); + case WMI_TKIP_MICERR_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n"); + return ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif); + case WMI_BSSINFO_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); + return ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); + case WMI_NEIGHBOR_REPORT_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); + return ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len, + vif); + case WMI_SCAN_COMPLETE_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); + return ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif); + case WMI_REPORT_STATISTICS_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n"); + return ath6kl_wmi_stats_event_rx(wmi, datap, len, vif); + case WMI_CAC_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n"); + return ath6kl_wmi_cac_event_rx(wmi, datap, len, vif); + case WMI_PSPOLL_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n"); + return ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif); + case WMI_DTIMEXPIRY_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); + return ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); + case WMI_ADDBA_REQ_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n"); + return ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif); + case WMI_DELBA_REQ_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n"); + return ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif); + case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, + "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); + return ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); + case WMI_REMAIN_ON_CHNL_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); + return ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); + case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, + "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n"); + return ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap, + len, vif); + case WMI_TX_STATUS_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n"); + return ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif); + case WMI_RX_PROBE_REQ_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n"); + return ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif); + case WMI_RX_ACTION_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); + return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); + default: + ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); return -EINVAL; } + return 0; +} + +static int ath6kl_wmi_proc_events(struct wmi *wmi, struct sk_buff *skb) +{ + struct wmi_cmd_hdr *cmd; + int ret = 0; + u32 len; + u16 id; + u8 if_idx; + u8 *datap; + cmd = (struct wmi_cmd_hdr *) skb->data; id = le16_to_cpu(cmd->cmd_id); if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK; skb_pull(skb, sizeof(struct wmi_cmd_hdr)); - datap = skb->data; len = skb->len; @@ -3298,15 +3537,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ", datap, len); - vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx); - if (!vif) { - ath6kl_dbg(ATH6KL_DBG_WMI, - "Wmi event for unavailable vif, vif_index:%d\n", - if_idx); - dev_kfree_skb(skb); - return -EINVAL; - } - switch (id) { case WMI_GET_BITRATE_CMDID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n"); @@ -3324,26 +3554,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n"); ret = ath6kl_wmi_ready_event_rx(wmi, datap, len); break; - case WMI_CONNECT_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n"); - ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif); - break; - case WMI_DISCONNECT_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n"); - ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif); - break; case WMI_PEER_NODE_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n"); ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len); break; - case WMI_TKIP_MICERR_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n"); - ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif); - break; - case WMI_BSSINFO_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); - ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif); - break; case WMI_REGDOMAIN_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n"); ath6kl_wmi_regdomain_event(wmi, datap, len); @@ -3352,23 +3566,10 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n"); ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len); break; - case WMI_NEIGHBOR_REPORT_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n"); - ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len, - vif); - break; - case WMI_SCAN_COMPLETE_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n"); - ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif); - break; case WMI_CMDERROR_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n"); ret = ath6kl_wmi_error_event_rx(wmi, datap, len); break; - case WMI_REPORT_STATISTICS_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n"); - ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif); - break; case WMI_RSSI_THRESHOLD_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n"); ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len); @@ -3388,10 +3589,6 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n"); ret = ath6kl_wmi_control_rx_xtnd(wmi, skb); break; - case WMI_CAC_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n"); - ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif); - break; case WMI_CHANNEL_CHANGE_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n"); break; @@ -3400,7 +3597,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) break; case WMI_TEST_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n"); - ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len); + ret = ath6kl_wmi_test_rx(wmi, datap, len); break; case WMI_GET_FIXRATES_CMDID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n"); @@ -3431,28 +3628,12 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n"); ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len); break; - case WMI_PSPOLL_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n"); - ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif); - break; - case WMI_DTIMEXPIRY_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n"); - ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif); - break; case WMI_SET_PARAMS_REPLY_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n"); break; - case WMI_ADDBA_REQ_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n"); - ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif); - break; case WMI_ADDBA_RESP_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n"); break; - case WMI_DELBA_REQ_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n"); - ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif); - break; case WMI_REPORT_BTCOEX_CONFIG_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n"); @@ -3465,47 +3646,39 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); ret = ath6kl_wmi_tx_complete_event_rx(datap, len); break; - case WMI_REMAIN_ON_CHNL_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); - ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); - break; - case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, - "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n"); - ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap, - len, vif); - break; - case WMI_TX_STATUS_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n"); - ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif); - break; - case WMI_RX_PROBE_REQ_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n"); - ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif); - break; case WMI_P2P_CAPABILITIES_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n"); ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len); break; - case WMI_RX_ACTION_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); - ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); - break; case WMI_P2P_INFO_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n"); ret = ath6kl_wmi_p2p_info_event_rx(datap, len); break; default: - ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id); - ret = -EINVAL; + /* may be the event is interface specific */ + ret = ath6kl_wmi_proc_events_vif(wmi, if_idx, id, datap, len); break; } dev_kfree_skb(skb); - return ret; } +/* Control Path */ +int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) +{ + if (WARN_ON(skb == NULL)) + return -EINVAL; + + if (skb->len < sizeof(struct wmi_cmd_hdr)) { + ath6kl_err("bad packet 1\n"); + dev_kfree_skb(skb); + return -EINVAL; + } + + return ath6kl_wmi_proc_events(wmi, skb); +} + void ath6kl_wmi_reset(struct wmi *wmi) { spin_lock_bh(&wmi->lock); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 42ac311eda4..4092e3e8079 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012 Qualcomm Atheros, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -110,6 +111,8 @@ struct wmi { u8 fat_pipe_exist; struct ath6kl *parent_dev; u8 pwr_mode; + + /* protects fat_pipe_exist and stream_exist_for_ac */ spinlock_t lock; enum htc_endpoint_id ep_id; struct sq_threshold_params @@ -149,8 +152,7 @@ enum wmi_msg_type { #define WMI_DATA_HDR_PS_MASK 0x1 #define WMI_DATA_HDR_PS_SHIFT 5 -#define WMI_DATA_HDR_MORE_MASK 0x1 -#define WMI_DATA_HDR_MORE_SHIFT 5 +#define WMI_DATA_HDR_MORE 0x20 enum wmi_data_hdr_data_type { WMI_DATA_HDR_DATA_TYPE_802_3 = 0, @@ -160,6 +162,13 @@ enum wmi_data_hdr_data_type { WMI_DATA_HDR_DATA_TYPE_ACL, }; +/* Bitmap of data header flags */ +enum wmi_data_hdr_flags { + WMI_DATA_HDR_FLAGS_MORE = 0x1, + WMI_DATA_HDR_FLAGS_EOSP = 0x2, + WMI_DATA_HDR_FLAGS_UAPSD = 0x4, +}; + #define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 #define WMI_DATA_HDR_DATA_TYPE_SHIFT 6 @@ -173,8 +182,12 @@ enum wmi_data_hdr_data_type { #define WMI_DATA_HDR_META_MASK 0x7 #define WMI_DATA_HDR_META_SHIFT 13 +/* Macros for operating on WMI_DATA_HDR (info3) field */ #define WMI_DATA_HDR_IF_IDX_MASK 0xF +#define WMI_DATA_HDR_TRIG 0x10 +#define WMI_DATA_HDR_EOSP 0x10 + struct wmi_data_hdr { s8 rssi; @@ -203,7 +216,8 @@ struct wmi_data_hdr { /* * usage of info3, 16-bit: * b3:b0 - Interface index - * b15:b4 - Reserved + * b4 - uAPSD trigger in rx & EOSP in tx + * b15:b5 - Reserved */ __le16 info3; } __packed; @@ -257,6 +271,9 @@ static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr) #define WMI_META_VERSION_1 0x01 #define WMI_META_VERSION_2 0x02 +/* Flag to signal to FW to calculate TCP checksum */ +#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01 + struct wmi_tx_meta_v1 { /* packet ID to identify the tx request */ u8 pkt_id; @@ -646,7 +663,6 @@ enum auth_mode { WPA2_AUTH_CCKM = 0x40, }; -#define WMI_MIN_KEY_INDEX 0 #define WMI_MAX_KEY_INDEX 3 #define WMI_MAX_KEY_LEN 32 @@ -984,6 +1000,12 @@ struct wmi_listen_int_cmd { __le16 num_beacons; } __packed; +/* WMI_SET_BMISS_TIME_CMDID */ +struct wmi_bmiss_time_cmd { + __le16 bmiss_time; + __le16 num_beacons; +}; + /* WMI_SET_POWER_MODE_CMDID */ enum wmi_power_mode { REC_POWER = 0x01, @@ -1001,7 +1023,7 @@ struct wmi_power_mode_cmd { */ enum power_save_fail_event_policy { SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1, - IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2, + IGNORE_PS_FAIL_DURING_SCAN = 2, }; struct wmi_power_params_cmd { @@ -1199,7 +1221,7 @@ struct wmi_snr_threshold_params_cmd { enum wmi_preamble_policy { WMI_IGNORE_BARKER_IN_ERP = 0, - WMI_DONOT_IGNORE_BARKER_IN_ERP + WMI_FOLLOW_BARKER_IN_ERP, }; struct wmi_set_lpreamble_cmd { @@ -1237,6 +1259,15 @@ enum target_event_report_config { NO_DISCONN_EVT_IN_RECONN }; +struct wmi_mcast_filter_cmd { + u8 mcast_all_enable; +} __packed; + +#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6 +struct wmi_mcast_filter_add_del_cmd { + u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; +} __packed; + /* Command Replies */ /* WMI_GET_CHANNEL_LIST_CMDID reply */ @@ -1335,6 +1366,8 @@ enum wmi_event_id { WMI_P2P_START_SDPD_EVENTID, WMI_P2P_SDPD_RX_EVENTID, + WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047, + WMI_THIN_RESERVED_START_EVENTID = 0x8000, /* Events in this range are reserved for thinmode */ WMI_THIN_RESERVED_END_EVENTID = 0x8fff, @@ -1903,7 +1936,7 @@ struct wow_filter { struct wmi_set_ip_cmd { /* IP in network byte order */ - __le32 ips[MAX_IP_ADDRS]; + __be32 ips[MAX_IP_ADDRS]; } __packed; enum ath6kl_wow_filters { @@ -2104,7 +2137,24 @@ struct wmi_rx_frame_format_cmd { u8 reserved[1]; } __packed; +struct wmi_ap_hidden_ssid_cmd { + u8 hidden_ssid; +} __packed; + /* AP mode events */ +struct wmi_ap_set_apsd_cmd { + u8 enable; +} __packed; + +enum wmi_ap_apsd_buffered_traffic_flags { + WMI_AP_APSD_NO_DELIVERY_FRAMES = 0x1, +}; + +struct wmi_ap_apsd_buffered_traffic_cmd { + __le16 aid; + __le16 bitmap; + __le32 flags; +} __packed; /* WMI_PS_POLL_EVENT */ struct wmi_pspoll_event { @@ -2321,7 +2371,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi); void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id); int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb); int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, - u8 msg_type, bool more_data, + u8 msg_type, u32 flags, enum wmi_data_hdr_data_type data_type, u8 meta_ver, void *tx_meta_info, u8 if_idx); @@ -2376,6 +2426,8 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx, u16 listen_interval, u16 listen_beacons); +int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx, + u16 bmiss_time, u16 num_beacons); int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode); int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period, u16 ps_poll_num, u16 dtim_policy, @@ -2417,7 +2469,8 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); s32 ath6kl_wmi_get_rate(s8 rate_index); -int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); +int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, + __be32 ips0, __be32 ips1); int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode); int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, @@ -2425,14 +2478,28 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, u32 filter, u16 host_req_delay); int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask); + u8 filter_offset, const u8 *filter, + const u8 *mask); int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); +int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); +int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, + u8 *filter, bool add_filter); +/* AP mode uAPSD */ +int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); +int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, + u8 if_idx, u16 aid, + u16 bitmap, u32 flags); + +u8 ath6kl_wmi_get_traffic_class(u8 user_priority); + +u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri); /* AP mode */ +int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable); int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, struct wmi_connect_cmd *p); @@ -2454,9 +2521,6 @@ int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable); int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur); -int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, - u32 wait, const u8 *data, u16 data_len); - int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq, u32 wait, const u8 *data, u16 data_len, u32 no_cck); diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index dc6be4afe8e..e507e78398f 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -6,6 +6,14 @@ config ATH9K_DFS_DEBUGFS def_bool y depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED +config ATH9K_BTCOEX_SUPPORT + bool "Atheros bluetooth coexistence support" + depends on (ATH9K || ATH9K_HTC) + default y + ---help--- + Say Y, if you want to use the ath9k/ath9k_htc radios together with + Bluetooth modules in the same system. + config ATH9K tristate "Atheros 802.11n wireless cards support" depends on MAC80211 @@ -73,6 +81,14 @@ config ATH9K_DFS_CERTIFIED developed. At this point enabling this option won't do anything except increase code size. +config ATH9K_MAC_DEBUG + bool "Atheros MAC statistics" + depends on ATH9K_DEBUGFS + default y + ---help--- + This option enables collection of statistics for Rx/Tx status + data and some other MAC related statistics + config ATH9K_RATE_CONTROL bool "Atheros ath9k rate control" depends on ATH9K @@ -81,14 +97,6 @@ config ATH9K_RATE_CONTROL Say Y, if you want to use the ath9k specific rate control module instead of minstrel_ht. -config ATH9K_BTCOEX_SUPPORT - bool "Atheros ath9k bluetooth coexistence support" - depends on ATH9K - default y - ---help--- - Say Y, if you want to use the ath9k radios together with - Bluetooth modules in the same system. - config ATH9K_HTC tristate "Atheros HTC based wireless cards support" depends on USB && MAC80211 diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index da02242499a..27d95fe5ade 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -3,9 +3,9 @@ ath9k-y += beacon.o \ init.o \ main.o \ recv.o \ - xmit.o \ - mci.o \ + xmit.o +ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ath9k-$(CONFIG_ATH9K_PCI) += pci.o ath9k-$(CONFIG_ATH9K_AHB) += ahb.o @@ -31,14 +31,14 @@ ath9k_hw-y:= \ eeprom_4k.o \ eeprom_9287.o \ ani.o \ - btcoex.o \ mac.o \ ar9002_mac.o \ ar9003_mac.o \ ar9003_eeprom.o \ - ar9003_paprd.o \ - ar9003_mci.o + ar9003_paprd.o +ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ + ar9003_mci.o obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index bc56f57b393..7e0ea4e9833 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -407,20 +407,20 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) if (aniState->ofdmWeakSigDetectOff) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, - true) == true) + true)) return; } if (aniState->firstepLevel > 0) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel - 1) == true) + aniState->firstepLevel - 1)) return; } } else { if (aniState->firstepLevel > 0) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, - aniState->firstepLevel - 1) == true) + aniState->firstepLevel - 1)) return; } } diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 86a891f93fc..d7d8e919914 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -834,9 +834,10 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); - if (AR_SREV_9271_10(ah)) - REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, - modesIndex, regWrites); + if (AR_SREV_9271_10(ah)) { + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA); + REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa); + } ENABLE_REGWRITE_BUFFER(ah); @@ -858,21 +859,11 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, REGWRITE_BUFFER_FLUSH(ah); - if (AR_SREV_9271(ah)) { - if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) - REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271, - modesIndex, regWrites); - else - REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, - modesIndex, regWrites); - } - REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); - if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { - REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - } ar5008_hw_override_ini(ah, chan); ar5008_hw_set_channel_regs(ah, chan); diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h index e8bdc75405f..ea4a230997a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h @@ -459,97 +459,6 @@ static const u32 ar5416Common_9100[][2] = { {0x0000a3e0, 0x000001ce}, }; -static const u32 ar5416Bank0_9100[][2] = { - /* Addr allmodes */ - {0x000098b0, 0x1e5795e5}, - {0x000098e0, 0x02008020}, -}; - -static const u32 ar5416BB_RfGain_9100[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00009a00, 0x00000000, 0x00000000}, - {0x00009a04, 0x00000040, 0x00000040}, - {0x00009a08, 0x00000080, 0x00000080}, - {0x00009a0c, 0x000001a1, 0x00000141}, - {0x00009a10, 0x000001e1, 0x00000181}, - {0x00009a14, 0x00000021, 0x000001c1}, - {0x00009a18, 0x00000061, 0x00000001}, - {0x00009a1c, 0x00000168, 0x00000041}, - {0x00009a20, 0x000001a8, 0x000001a8}, - {0x00009a24, 0x000001e8, 0x000001e8}, - {0x00009a28, 0x00000028, 0x00000028}, - {0x00009a2c, 0x00000068, 0x00000068}, - {0x00009a30, 0x00000189, 0x000000a8}, - {0x00009a34, 0x000001c9, 0x00000169}, - {0x00009a38, 0x00000009, 0x000001a9}, - {0x00009a3c, 0x00000049, 0x000001e9}, - {0x00009a40, 0x00000089, 0x00000029}, - {0x00009a44, 0x00000170, 0x00000069}, - {0x00009a48, 0x000001b0, 0x00000190}, - {0x00009a4c, 0x000001f0, 0x000001d0}, - {0x00009a50, 0x00000030, 0x00000010}, - {0x00009a54, 0x00000070, 0x00000050}, - {0x00009a58, 0x00000191, 0x00000090}, - {0x00009a5c, 0x000001d1, 0x00000151}, - {0x00009a60, 0x00000011, 0x00000191}, - {0x00009a64, 0x00000051, 0x000001d1}, - {0x00009a68, 0x00000091, 0x00000011}, - {0x00009a6c, 0x000001b8, 0x00000051}, - {0x00009a70, 0x000001f8, 0x00000198}, - {0x00009a74, 0x00000038, 0x000001d8}, - {0x00009a78, 0x00000078, 0x00000018}, - {0x00009a7c, 0x00000199, 0x00000058}, - {0x00009a80, 0x000001d9, 0x00000098}, - {0x00009a84, 0x00000019, 0x00000159}, - {0x00009a88, 0x00000059, 0x00000199}, - {0x00009a8c, 0x00000099, 0x000001d9}, - {0x00009a90, 0x000000d9, 0x00000019}, - {0x00009a94, 0x000000f9, 0x00000059}, - {0x00009a98, 0x000000f9, 0x00000099}, - {0x00009a9c, 0x000000f9, 0x000000d9}, - {0x00009aa0, 0x000000f9, 0x000000f9}, - {0x00009aa4, 0x000000f9, 0x000000f9}, - {0x00009aa8, 0x000000f9, 0x000000f9}, - {0x00009aac, 0x000000f9, 0x000000f9}, - {0x00009ab0, 0x000000f9, 0x000000f9}, - {0x00009ab4, 0x000000f9, 0x000000f9}, - {0x00009ab8, 0x000000f9, 0x000000f9}, - {0x00009abc, 0x000000f9, 0x000000f9}, - {0x00009ac0, 0x000000f9, 0x000000f9}, - {0x00009ac4, 0x000000f9, 0x000000f9}, - {0x00009ac8, 0x000000f9, 0x000000f9}, - {0x00009acc, 0x000000f9, 0x000000f9}, - {0x00009ad0, 0x000000f9, 0x000000f9}, - {0x00009ad4, 0x000000f9, 0x000000f9}, - {0x00009ad8, 0x000000f9, 0x000000f9}, - {0x00009adc, 0x000000f9, 0x000000f9}, - {0x00009ae0, 0x000000f9, 0x000000f9}, - {0x00009ae4, 0x000000f9, 0x000000f9}, - {0x00009ae8, 0x000000f9, 0x000000f9}, - {0x00009aec, 0x000000f9, 0x000000f9}, - {0x00009af0, 0x000000f9, 0x000000f9}, - {0x00009af4, 0x000000f9, 0x000000f9}, - {0x00009af8, 0x000000f9, 0x000000f9}, - {0x00009afc, 0x000000f9, 0x000000f9}, -}; - -static const u32 ar5416Bank1_9100[][2] = { - /* Addr allmodes */ - {0x000098b0, 0x02108421}, - {0x000098ec, 0x00000008}, -}; - -static const u32 ar5416Bank2_9100[][2] = { - /* Addr allmodes */ - {0x000098b0, 0x0e73ff17}, - {0x000098e0, 0x00000420}, -}; - -static const u32 ar5416Bank3_9100[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x000098f0, 0x01400018, 0x01c00018}, -}; - static const u32 ar5416Bank6_9100[][3] = { /* Addr 5G_HT20 5G_HT40 */ {0x0000989c, 0x00000000, 0x00000000}, @@ -624,13 +533,6 @@ static const u32 ar5416Bank6TPC_9100[][3] = { {0x000098d0, 0x0000000f, 0x0010000f}, }; -static const u32 ar5416Bank7_9100[][2] = { - /* Addr allmodes */ - {0x0000989c, 0x00000500}, - {0x0000989c, 0x00000800}, - {0x000098cc, 0x0000000e}, -}; - static const u32 ar5416Addac_9100[][2] = { /* Addr allmodes */ {0x0000989c, 0x00000000}, @@ -1113,178 +1015,6 @@ static const u32 ar5416Common_9160[][2] = { {0x0000a3e0, 0x000001ce}, }; -static const u32 ar5416Bank0_9160[][2] = { - /* Addr allmodes */ - {0x000098b0, 0x1e5795e5}, - {0x000098e0, 0x02008020}, -}; - -static const u32 ar5416BB_RfGain_9160[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00009a00, 0x00000000, 0x00000000}, - {0x00009a04, 0x00000040, 0x00000040}, - {0x00009a08, 0x00000080, 0x00000080}, - {0x00009a0c, 0x000001a1, 0x00000141}, - {0x00009a10, 0x000001e1, 0x00000181}, - {0x00009a14, 0x00000021, 0x000001c1}, - {0x00009a18, 0x00000061, 0x00000001}, - {0x00009a1c, 0x00000168, 0x00000041}, - {0x00009a20, 0x000001a8, 0x000001a8}, - {0x00009a24, 0x000001e8, 0x000001e8}, - {0x00009a28, 0x00000028, 0x00000028}, - {0x00009a2c, 0x00000068, 0x00000068}, - {0x00009a30, 0x00000189, 0x000000a8}, - {0x00009a34, 0x000001c9, 0x00000169}, - {0x00009a38, 0x00000009, 0x000001a9}, - {0x00009a3c, 0x00000049, 0x000001e9}, - {0x00009a40, 0x00000089, 0x00000029}, - {0x00009a44, 0x00000170, 0x00000069}, - {0x00009a48, 0x000001b0, 0x00000190}, - {0x00009a4c, 0x000001f0, 0x000001d0}, - {0x00009a50, 0x00000030, 0x00000010}, - {0x00009a54, 0x00000070, 0x00000050}, - {0x00009a58, 0x00000191, 0x00000090}, - {0x00009a5c, 0x000001d1, 0x00000151}, - {0x00009a60, 0x00000011, 0x00000191}, - {0x00009a64, 0x00000051, 0x000001d1}, - {0x00009a68, 0x00000091, 0x00000011}, - {0x00009a6c, 0x000001b8, 0x00000051}, - {0x00009a70, 0x000001f8, 0x00000198}, - {0x00009a74, 0x00000038, 0x000001d8}, - {0x00009a78, 0x00000078, 0x00000018}, - {0x00009a7c, 0x00000199, 0x00000058}, - {0x00009a80, 0x000001d9, 0x00000098}, - {0x00009a84, 0x00000019, 0x00000159}, - {0x00009a88, 0x00000059, 0x00000199}, - {0x00009a8c, 0x00000099, 0x000001d9}, - {0x00009a90, 0x000000d9, 0x00000019}, - {0x00009a94, 0x000000f9, 0x00000059}, - {0x00009a98, 0x000000f9, 0x00000099}, - {0x00009a9c, 0x000000f9, 0x000000d9}, - {0x00009aa0, 0x000000f9, 0x000000f9}, - {0x00009aa4, 0x000000f9, 0x000000f9}, - {0x00009aa8, 0x000000f9, 0x000000f9}, - {0x00009aac, 0x000000f9, 0x000000f9}, - {0x00009ab0, 0x000000f9, 0x000000f9}, - {0x00009ab4, 0x000000f9, 0x000000f9}, - {0x00009ab8, 0x000000f9, 0x000000f9}, - {0x00009abc, 0x000000f9, 0x000000f9}, - {0x00009ac0, 0x000000f9, 0x000000f9}, - {0x00009ac4, 0x000000f9, 0x000000f9}, - {0x00009ac8, 0x000000f9, 0x000000f9}, - {0x00009acc, 0x000000f9, 0x000000f9}, - {0x00009ad0, 0x000000f9, 0x000000f9}, - {0x00009ad4, 0x000000f9, 0x000000f9}, - {0x00009ad8, 0x000000f9, 0x000000f9}, - {0x00009adc, 0x000000f9, 0x000000f9}, - {0x00009ae0, 0x000000f9, 0x000000f9}, - {0x00009ae4, 0x000000f9, 0x000000f9}, - {0x00009ae8, 0x000000f9, 0x000000f9}, - {0x00009aec, 0x000000f9, 0x000000f9}, - {0x00009af0, 0x000000f9, 0x000000f9}, - {0x00009af4, 0x000000f9, 0x000000f9}, - {0x00009af8, 0x000000f9, 0x000000f9}, - {0x00009afc, 0x000000f9, 0x000000f9}, -}; - -static const u32 ar5416Bank1_9160[][2] = { - /* Addr allmodes */ - {0x000098b0, 0x02108421}, - {0x000098ec, 0x00000008}, -}; - -static const u32 ar5416Bank2_9160[][2] = { - /* Addr allmodes */ - {0x000098b0, 0x0e73ff17}, - {0x000098e0, 0x00000420}, -}; - -static const u32 ar5416Bank3_9160[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x000098f0, 0x01400018, 0x01c00018}, -}; - -static const u32 ar5416Bank6_9160[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x0000989c, 0x00000000, 0x00000000}, - {0x0000989c, 0x00000000, 0x00000000}, - {0x0000989c, 0x00000000, 0x00000000}, - {0x0000989c, 0x00e00000, 0x00e00000}, - {0x0000989c, 0x005e0000, 0x005e0000}, - {0x0000989c, 0x00120000, 0x00120000}, - {0x0000989c, 0x00620000, 0x00620000}, - {0x0000989c, 0x00020000, 0x00020000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x40ff0000, 0x40ff0000}, - {0x0000989c, 0x005f0000, 0x005f0000}, - {0x0000989c, 0x00870000, 0x00870000}, - {0x0000989c, 0x00f90000, 0x00f90000}, - {0x0000989c, 0x007b0000, 0x007b0000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x00f50000, 0x00f50000}, - {0x0000989c, 0x00dc0000, 0x00dc0000}, - {0x0000989c, 0x00110000, 0x00110000}, - {0x0000989c, 0x006100a8, 0x006100a8}, - {0x0000989c, 0x004210a2, 0x004210a2}, - {0x0000989c, 0x0014008f, 0x0014008f}, - {0x0000989c, 0x00c40003, 0x00c40003}, - {0x0000989c, 0x003000f2, 0x003000f2}, - {0x0000989c, 0x00440016, 0x00440016}, - {0x0000989c, 0x00410040, 0x00410040}, - {0x0000989c, 0x0001805e, 0x0001805e}, - {0x0000989c, 0x0000c0ab, 0x0000c0ab}, - {0x0000989c, 0x000000f1, 0x000000f1}, - {0x0000989c, 0x00002081, 0x00002081}, - {0x0000989c, 0x000000d4, 0x000000d4}, - {0x000098d0, 0x0000000f, 0x0010000f}, -}; - -static const u32 ar5416Bank6TPC_9160[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x0000989c, 0x00000000, 0x00000000}, - {0x0000989c, 0x00000000, 0x00000000}, - {0x0000989c, 0x00000000, 0x00000000}, - {0x0000989c, 0x00e00000, 0x00e00000}, - {0x0000989c, 0x005e0000, 0x005e0000}, - {0x0000989c, 0x00120000, 0x00120000}, - {0x0000989c, 0x00620000, 0x00620000}, - {0x0000989c, 0x00020000, 0x00020000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x40ff0000, 0x40ff0000}, - {0x0000989c, 0x005f0000, 0x005f0000}, - {0x0000989c, 0x00870000, 0x00870000}, - {0x0000989c, 0x00f90000, 0x00f90000}, - {0x0000989c, 0x007b0000, 0x007b0000}, - {0x0000989c, 0x00ff0000, 0x00ff0000}, - {0x0000989c, 0x00f50000, 0x00f50000}, - {0x0000989c, 0x00dc0000, 0x00dc0000}, - {0x0000989c, 0x00110000, 0x00110000}, - {0x0000989c, 0x006100a8, 0x006100a8}, - {0x0000989c, 0x00423022, 0x00423022}, - {0x0000989c, 0x2014008f, 0x2014008f}, - {0x0000989c, 0x00c40002, 0x00c40002}, - {0x0000989c, 0x003000f2, 0x003000f2}, - {0x0000989c, 0x00440016, 0x00440016}, - {0x0000989c, 0x00410040, 0x00410040}, - {0x0000989c, 0x0001805e, 0x0001805e}, - {0x0000989c, 0x0000c0ab, 0x0000c0ab}, - {0x0000989c, 0x000000e1, 0x000000e1}, - {0x0000989c, 0x00007080, 0x00007080}, - {0x0000989c, 0x000000d4, 0x000000d4}, - {0x000098d0, 0x0000000f, 0x0010000f}, -}; - -static const u32 ar5416Bank7_9160[][2] = { - /* Addr allmodes */ - {0x0000989c, 0x00000500}, - {0x0000989c, 0x00000800}, - {0x000098cc, 0x0000000e}, -}; - static const u32 ar5416Addac_9160[][2] = { /* Addr allmodes */ {0x0000989c, 0x00000000}, diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index d190411ac8f..d9a69fc470c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -34,74 +34,37 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9271Modes_9271), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, ARRAY_SIZE(ar9271Common_9271), 2); - INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, - ar9271Common_normal_cck_fir_coeff_9271, - ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2); - INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271, - ar9271Common_japan_2484_cck_fir_coeff_9271, - ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2); - INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, - ar9271Modes_9271_1_0_only, - ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5); INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); - INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271, - ar9271Modes_high_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); - INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, - ar9271Modes_normal_power_tx_gain_9271, - ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); return; } + if (ah->config.pcie_clock_req) + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9280PciePhy_clkreq_off_L1_9280, + ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2); + else + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9280PciePhy_clkreq_always_on_L1_9280, + ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); + if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, ARRAY_SIZE(ar9287Modes_9287_1_1), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, ARRAY_SIZE(ar9287Common_9287_1_1), 2); - if (ah->config.pcie_clock_req) - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9287PciePhy_clkreq_off_L1_9287_1_1, - ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2); - else - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9287PciePhy_clkreq_always_on_L1_9287_1_1, - ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1), - 2); } else if (AR_SREV_9285_12_OR_LATER(ah)) { - - INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, ARRAY_SIZE(ar9285Modes_9285_1_2), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, ARRAY_SIZE(ar9285Common_9285_1_2), 2); - - if (ah->config.pcie_clock_req) { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9285PciePhy_clkreq_off_L1_9285_1_2, - ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); - } else { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9285PciePhy_clkreq_always_on_L1_9285_1_2, - ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), - 2); - } } else if (AR_SREV_9280_20_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, ARRAY_SIZE(ar9280Modes_9280_2), 5); INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, ARRAY_SIZE(ar9280Common_9280_2), 2); - if (ah->config.pcie_clock_req) { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9280PciePhy_clkreq_off_L1_9280, - ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2); - } else { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9280PciePhy_clkreq_always_on_L1_9280, - ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); - } - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9280Modes_fast_clock_9280_2, ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); } else if (AR_SREV_9160_10_OR_LATER(ah)) { @@ -109,22 +72,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar5416Modes_9160), 5); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, ARRAY_SIZE(ar5416Common_9160), 2); - INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160, - ARRAY_SIZE(ar5416Bank0_9160), 2); - INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160, - ARRAY_SIZE(ar5416BB_RfGain_9160), 3); - INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160, - ARRAY_SIZE(ar5416Bank1_9160), 2); - INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160, - ARRAY_SIZE(ar5416Bank2_9160), 2); - INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160, - ARRAY_SIZE(ar5416Bank3_9160), 3); - INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160, - ARRAY_SIZE(ar5416Bank6_9160), 3); - INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160, - ARRAY_SIZE(ar5416Bank6TPC_9160), 3); - INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160, - ARRAY_SIZE(ar5416Bank7_9160), 2); if (AR_SREV_9160_11(ah)) { INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160_1_1, @@ -138,22 +85,8 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar5416Modes_9100), 5); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, ARRAY_SIZE(ar5416Common_9100), 2); - INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100, - ARRAY_SIZE(ar5416Bank0_9100), 2); - INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100, - ARRAY_SIZE(ar5416BB_RfGain_9100), 3); - INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100, - ARRAY_SIZE(ar5416Bank1_9100), 2); - INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100, - ARRAY_SIZE(ar5416Bank2_9100), 2); - INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100, - ARRAY_SIZE(ar5416Bank3_9100), 3); INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, ARRAY_SIZE(ar5416Bank6_9100), 3); - INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, - ARRAY_SIZE(ar5416Bank6TPC_9100), 3); - INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100, - ARRAY_SIZE(ar5416Bank7_9100), 2); INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, ARRAY_SIZE(ar5416Addac_9100), 2); } else { @@ -161,24 +94,37 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar5416Modes), 5); INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, ARRAY_SIZE(ar5416Common), 2); - INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, - ARRAY_SIZE(ar5416Bank0), 2); + INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, + ARRAY_SIZE(ar5416Bank6TPC), 3); + INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, + ARRAY_SIZE(ar5416Addac), 2); + } + + if (!AR_SREV_9280_20_OR_LATER(ah)) { + /* Common for AR5416, AR913x, AR9160 */ INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, ARRAY_SIZE(ar5416BB_RfGain), 3); + + INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, + ARRAY_SIZE(ar5416Bank0), 2); INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, ARRAY_SIZE(ar5416Bank1), 2); INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, ARRAY_SIZE(ar5416Bank2), 2); INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, ARRAY_SIZE(ar5416Bank3), 3); - INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, - ARRAY_SIZE(ar5416Bank6), 3); - INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, - ARRAY_SIZE(ar5416Bank6TPC), 3); INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, ARRAY_SIZE(ar5416Bank7), 2); - INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, - ARRAY_SIZE(ar5416Addac), 2); + + /* Common for AR5416, AR9160 */ + if (!AR_SREV_9100(ah)) + INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, + ARRAY_SIZE(ar5416Bank6), 3); + + /* Common for AR913x, AR9160 */ + if (!AR_SREV_5416(ah)) + INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, + ARRAY_SIZE(ar5416Bank6TPC_9100), 3); } /* iniAddac needs to be modified for these chips */ @@ -199,11 +145,6 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) INI_RA(addac, 31,1) = 0; } } -} - -/* Support for Japan ch.14 (2484) spread */ -void ar9002_hw_cck_chan14_spread(struct ath_hw *ah) -{ if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniCckfirNormal, ar9287Common_normal_cck_fir_coeff_9287_1_1, @@ -243,14 +184,10 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) } } -static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) +static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) { - u32 txgain_type; - if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) { - txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); - if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9280Modes_high_power_tx_gain_9280_2, @@ -266,8 +203,22 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) } } +static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) +{ + if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9271Modes_high_power_tx_gain_9271, + ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9271Modes_normal_power_tx_gain_9271, + ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); +} + static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) { + u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); + if (AR_SREV_9287_11_OR_LATER(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9287Modes_rx_gain_9287_1_1, @@ -275,15 +226,15 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) else if (AR_SREV_9280_20(ah)) ar9280_20_hw_init_rxgain_ini(ah); - if (AR_SREV_9287_11_OR_LATER(ah)) { + if (AR_SREV_9271(ah)) { + ar9271_hw_init_txgain_ini(ah, txgain_type); + } else if (AR_SREV_9287_11_OR_LATER(ah)) { INIT_INI_ARRAY(&ah->iniModesTxGain, ar9287Modes_tx_gain_9287_1_1, ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); } else if (AR_SREV_9280_20(ah)) { - ar9280_20_hw_init_txgain_ini(ah); + ar9280_20_hw_init_txgain_ini(ah, txgain_type); } else if (AR_SREV_9285_12_OR_LATER(ah)) { - u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); - /* txgain table */ if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { if (AR_SREV_9285E_20(ah)) { diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 863db321070..4d18c66a679 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h @@ -925,34 +925,6 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { {0x00004044, 0x00000000}, }; -static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffd}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffc}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - static const u32 ar9285Modes_9285_1_2[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, @@ -1743,34 +1715,6 @@ static const u32 ar9285Modes_XE2_0_high_power[][5] = { {0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7}, }; -static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffd}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffc}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - static const u32 ar9287Modes_9287_1_1[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160}, @@ -2512,34 +2456,6 @@ static const u32 ar9287Modes_rx_gain_9287_1_1[][5] = { {0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067}, }; -static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffd}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { - /* Addr allmodes */ - {0x00004040, 0x9248fd00}, - {0x00004040, 0x24924924}, - {0x00004040, 0xa8000019}, - {0x00004040, 0x13160820}, - {0x00004040, 0xe5980560}, - {0x00004040, 0xc01dcffc}, - {0x00004040, 0x1aaabe41}, - {0x00004040, 0xbe105554}, - {0x00004040, 0x00043007}, - {0x00004044, 0x00000000}, -}; - static const u32 ar9271Modes_9271[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, @@ -3176,26 +3092,6 @@ static const u32 ar9271Common_9271[][2] = { {0x0000d384, 0xf3307ff0}, }; -static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = { - /* Addr allmodes */ - {0x0000a1f4, 0x00fffeff}, - {0x0000a1f8, 0x00f5f9ff}, - {0x0000a1fc, 0xb79f6427}, -}; - -static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = { - /* Addr allmodes */ - {0x0000a1f4, 0x00000000}, - {0x0000a1f8, 0xefff0301}, - {0x0000a1fc, 0xca9228ee}, -}; - -static const u32 ar9271Modes_9271_1_0_only[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311}, - {0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001}, -}; - static const u32 ar9271Modes_9271_ANI_reg[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2}, diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 7b6417b5212..aa2abaf31cb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -347,15 +347,12 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { struct ar5416_desc *ads = AR5416DESC(ds); - struct ath9k_hw_capabilities *pCap = &ah->caps; ads->ds_ctl1 = size & AR_BufLen; if (flags & ATH9K_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxIntrReq; - ads->ds_rxstatus8 &= ~AR_RxDone; - if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) - memset(&(ads->u), 0, sizeof(ads->u)); + memset(&ads->u.rx, 0, sizeof(ads->u.rx)); } EXPORT_SYMBOL(ath9k_hw_setuprxdesc); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index 453af6dc514..f9eb2c35716 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -60,6 +60,8 @@ #define AR_PHY_RF_CTL3 0x9828 #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 +#define AR_PHY_TX_END_TO_ADC_ON 0xFF000000 +#define AR_PHY_TX_END_TO_ADC_ON_S 24 #define AR_PHY_ADC_CTL 0x982C #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 026f9de15d1..46c79a3d473 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -295,266 +295,6 @@ static const u32 ar9300_2p2_radio_core[][2] = { {0x00016bd4, 0x00000000}, }; -static const u32 ar9300Common_rx_gain_table_merlin_2p2[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - static const u32 ar9300_2p2_mac_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, @@ -572,48 +312,6 @@ static const u32 ar9300_2p2_soc_postamble[][5] = { {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, }; -static const u32 ar9200_merlin_2p2_radio_core[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - static const u32 ar9300_2p2_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8e70f0bc073..63089cc1faf 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -925,7 +925,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_cal_data *caldata = ah->caldata; - struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; bool txiqcal_done = false, txclcal_done = false; bool is_reusable = true, status = true; bool run_rtt_cal = false, run_agc_cal; @@ -998,30 +997,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, } else if (caldata && !caldata->done_txiqcal_once) run_agc_cal = true; - if (mci && IS_CHAN_2GHZ(chan) && - (mci_hw->bt_state == MCI_BT_AWAKE) && - run_agc_cal && - !(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) { - - u32 pld[4] = {0, 0, 0, 0}; - - /* send CAL_REQ only when BT is AWAKE. */ - ath_dbg(common, MCI, "MCI send WLAN_CAL_REQ 0x%x\n", - mci_hw->wlan_cal_seq); - MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ); - pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++; - ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); - - /* Wait BT_CAL_GRANT for 50ms */ - ath_dbg(common, MCI, "MCI wait for BT_CAL_GRANT\n"); - - if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) - ath_dbg(common, MCI, "MCI got BT_CAL_GRANT\n"); - else { - is_reusable = false; - ath_dbg(common, MCI, "\nMCI BT is not responding\n"); - } - } + if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) + ar9003_mci_init_cal_req(ah, &is_reusable); txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); @@ -1041,19 +1018,8 @@ skip_tx_iqcal: 0, AH_WAIT_TIMEOUT); } - if (mci && IS_CHAN_2GHZ(chan) && - (mci_hw->bt_state == MCI_BT_AWAKE) && - run_agc_cal && - !(mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) { - - u32 pld[4] = {0, 0, 0, 0}; - - ath_dbg(common, MCI, "MCI Send WLAN_CAL_DONE 0x%x\n", - mci_hw->wlan_cal_done); - MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE); - pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++; - ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); - } + if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) + ar9003_mci_init_cal_done(ah); if (rtt && !run_rtt_cal) { agc_ctrl |= agc_supp_cals; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 9fbcbddea16..6bb4db052bb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3603,10 +3603,6 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); if (AR_SREV_9462(ah)) { - if (AR_SREV_9462_10(ah)) { - value &= ~AR_SWITCH_TABLE_COM_SPDT; - value |= 0x00100000; - } REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_AR9462_ALL, value); } else diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index fb937ba93e0..0f56e322dd3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -22,7 +22,6 @@ #include "ar9330_1p1_initvals.h" #include "ar9330_1p2_initvals.h" #include "ar9580_1p0_initvals.h" -#include "ar9462_1p0_initvals.h" #include "ar9462_2p0_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -88,11 +87,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* additional clock settings */ if (ah->is_clk_25mhz) - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p1_xtal_25M, ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); else - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p1_xtal_40M, ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); } else if (AR_SREV_9330_12(ah)) { @@ -141,11 +140,11 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* additional clock settings */ if (ah->is_clk_25mhz) - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p2_xtal_25M, ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); else - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniAdditional, ar9331_1p2_xtal_40M, ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); } else if (AR_SREV_9340(ah)) { @@ -195,15 +194,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), 5); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9340Modes_fast_clock_1p0, ARRAY_SIZE(ar9340Modes_fast_clock_1p0), 3); - INIT_INI_ARRAY(&ah->iniModesAdditional_40M, - ar9340_1p0_radio_core_40M, - ARRAY_SIZE(ar9340_1p0_radio_core_40M), - 2); + if (!ah->is_clk_25mhz) + INIT_INI_ARRAY(&ah->iniAdditional, + ar9340_1p0_radio_core_40M, + ARRAY_SIZE(ar9340_1p0_radio_core_40M), + 2); } else if (AR_SREV_9485_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -264,63 +264,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ar9485_1_1_pcie_phy_clkreq_disable_L1, ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), 2); - } else if (AR_SREV_9462_10(ah)) { - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_1p0_mac_core, - ARRAY_SIZE(ar9462_1p0_mac_core), 2); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], - ar9462_1p0_mac_postamble, - ARRAY_SIZE(ar9462_1p0_mac_postamble), - 5); - - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], - ar9462_1p0_baseband_core, - ARRAY_SIZE(ar9462_1p0_baseband_core), - 2); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], - ar9462_1p0_baseband_postamble, - ARRAY_SIZE(ar9462_1p0_baseband_postamble), 5); - - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], - ar9462_1p0_radio_core, - ARRAY_SIZE(ar9462_1p0_radio_core), 2); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], - ar9462_1p0_radio_postamble, - ARRAY_SIZE(ar9462_1p0_radio_postamble), 5); - - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], - ar9462_1p0_soc_preamble, - ARRAY_SIZE(ar9462_1p0_soc_preamble), 2); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], - ar9462_1p0_soc_postamble, - ARRAY_SIZE(ar9462_1p0_soc_postamble), 5); - - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9462_common_rx_gain_table_1p0, - ARRAY_SIZE(ar9462_common_rx_gain_table_1p0), 2); - - /* Awake -> Sleep Setting */ - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9462_pcie_phy_clkreq_disable_L1_1p0, - ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0), - 2); - - /* Sleep -> Awake Setting */ - INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9462_pcie_phy_clkreq_disable_L1_1p0, - ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0), - 2); - - INIT_INI_ARRAY(&ah->iniModesAdditional, - ar9462_modes_fast_clock_1p0, - ARRAY_SIZE(ar9462_modes_fast_clock_1p0), 3); - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - AR9462_BB_CTX_COEFJ(1p0), - ARRAY_SIZE(AR9462_BB_CTX_COEFJ(1p0)), 2); - } else if (AR_SREV_9462_20(ah)) { INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -379,7 +322,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 2); /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9462_modes_fast_clock_2p0, ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3); @@ -436,7 +379,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), 5); - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9580_1p0_modes_fast_clock, ARRAY_SIZE(ar9580_1p0_modes_fast_clock), 3); @@ -503,7 +446,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 2); /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, + INIT_INI_ARRAY(&ah->iniModesFastClock, ar9300Modes_fast_clock_2p2, ARRAY_SIZE(ar9300Modes_fast_clock_2p2), 3); @@ -537,11 +480,6 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) ar9580_1p0_lowest_ob_db_tx_gain_table, ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), 5); - else if (AR_SREV_9462_10(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9462_modes_low_ob_db_tx_gain_table_1p0, - ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_1p0), - 5); else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9462_modes_low_ob_db_tx_gain_table_2p0, @@ -581,11 +519,6 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) ar9580_1p0_high_ob_db_tx_gain_table, ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), 5); - else if (AR_SREV_9462_10(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9462_modes_high_ob_db_tx_gain_table_1p0, - ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_1p0), - 5); else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9462_modes_high_ob_db_tx_gain_table_2p0, @@ -712,11 +645,6 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) ar9580_1p0_rx_gain_table, ARRAY_SIZE(ar9580_1p0_rx_gain_table), 2); - else if (AR_SREV_9462_10(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9462_common_rx_gain_table_1p0, - ARRAY_SIZE(ar9462_common_rx_gain_table_1p0), - 2); else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9462_common_rx_gain_table_2p0, @@ -751,11 +679,6 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) ar9485Common_wo_xlna_rx_gain_1_1, ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); - else if (AR_SREV_9462_10(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9462_common_wo_xlna_rx_gain_table_1p0, - ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_1p0), - 2); else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9462_common_wo_xlna_rx_gain_table_2p0, @@ -775,14 +698,10 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) { - if (AR_SREV_9462_10(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9462_common_mixed_rx_gain_table_1p0, - ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_1p0), 2); - else if (AR_SREV_9462_20(ah)) + if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9462_common_mixed_rx_gain_table_2p0, - ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2); + ar9462_common_mixed_rx_gain_table_2p0, + ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2); } static void ar9003_rx_gain_table_apply(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 09b8c9dbf78..a66a13b7684 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -16,6 +16,7 @@ #include <linux/export.h> #include "hw.h" #include "ar9003_mac.h" +#include "ar9003_mci.h" static void ar9003_hw_rx_enable(struct ath_hw *hw) { @@ -28,11 +29,14 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) struct ar9003_txc *ads = ds; int checksum = 0; u32 val, ctl12, ctl17; + u8 desc_len; + + desc_len = (AR_SREV_9462(ah) ? 0x18 : 0x17); val = (ATHEROS_VENDOR_ID << AR_DescId_S) | (1 << AR_TxRxDesc_S) | (1 << AR_CtrlStat_S) | - (i->qcu << AR_TxQcuNum_S) | 0x17; + (i->qcu << AR_TxQcuNum_S) | desc_len; checksum += val; ACCESS_ONCE(ads->info) = val; @@ -81,6 +85,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) ads->ctl20 = 0; ads->ctl21 = 0; ads->ctl22 = 0; + ads->ctl23 = 0; ctl17 = SM(i->keytype, AR_EncrType); if (!i->is_first) { @@ -176,7 +181,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) u32 mask2 = 0; struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 sync_cause = 0, async_cause; async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); @@ -298,32 +302,8 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ar9003_hw_bb_watchdog_read(ah); } - if (async_cause & AR_INTR_ASYNC_MASK_MCI) { - u32 raw_intr, rx_msg_intr; - - rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); - raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW); - - if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) - ath_dbg(common, MCI, - "MCI gets 0xdeadbeef during MCI int processing new raw_intr=0x%08x, new rx_msg_raw=0x%08x, raw_intr=0x%08x, rx_msg_raw=0x%08x\n", - raw_intr, rx_msg_intr, mci->raw_intr, - mci->rx_msg_intr); - else { - mci->rx_msg_intr |= rx_msg_intr; - mci->raw_intr |= raw_intr; - *masked |= ATH9K_INT_MCI; - - if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) - mci->cont_status = - REG_READ(ah, AR_MCI_CONT_STATUS); - - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr); - REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr); - ath_dbg(common, MCI, "AR_INTR_SYNC_MCI\n"); - - } - } + if (async_cause & AR_INTR_ASYNC_MASK_MCI) + ar9003_mci_get_isr(ah, masked); if (sync_cause) { if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { @@ -346,7 +326,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { - struct ar9003_txc *txc = (struct ar9003_txc *) ds; struct ar9003_txs *ads; u32 status; @@ -356,11 +335,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, if ((status & AR_TxDone) == 0) return -EINPROGRESS; - ts->qid = MS(ads->ds_info, AR_TxQcuNum); - if (!txc || (MS(txc->info, AR_TxQcuNum) == ts->qid)) - ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; - else - return -ENOENT; + ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || (MS(ads->ds_info, AR_TxRxDesc) != 1)) { @@ -374,6 +349,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, ts->ts_seqnum = MS(status, AR_SeqNum); ts->tid = MS(status, AR_TxTid); + ts->qid = MS(ads->ds_info, AR_TxQcuNum); ts->desc_id = MS(ads->status1, AR_TxDescId); ts->ts_tstamp = ads->status4; ts->ts_status = 0; @@ -460,20 +436,14 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; unsigned int phyerr; - /* TODO: byte swap on big endian for ar9300_10 */ - - if (!rxs) { - if ((rxsp->status11 & AR_RxDone) == 0) - return -EINPROGRESS; - - if (MS(rxsp->ds_info, AR_DescId) != 0x168c) - return -EINVAL; + if ((rxsp->status11 & AR_RxDone) == 0) + return -EINPROGRESS; - if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) - return -EINPROGRESS; + if (MS(rxsp->ds_info, AR_DescId) != 0x168c) + return -EINVAL; - return 0; - } + if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) + return -EINPROGRESS; rxs->rs_status = 0; rxs->rs_flags = 0; @@ -530,7 +500,11 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, */ if (rxsp->status11 & AR_CRCErr) rxs->rs_status |= ATH9K_RXERR_CRC; - else if (rxsp->status11 & AR_PHYErr) { + else if (rxsp->status11 & AR_DecryptCRCErr) + rxs->rs_status |= ATH9K_RXERR_DECRYPT; + else if (rxsp->status11 & AR_MichaelErr) + rxs->rs_status |= ATH9K_RXERR_MIC; + if (rxsp->status11 & AR_PHYErr) { phyerr = MS(rxsp->status11, AR_PHYErrCode); /* * If we reach a point here where AR_PostDelimCRCErr is @@ -552,11 +526,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_status |= ATH9K_RXERR_PHY; rxs->rs_phyerr = phyerr; } - - } else if (rxsp->status11 & AR_DecryptCRCErr) - rxs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (rxsp->status11 & AR_MichaelErr) - rxs->rs_status |= ATH9K_RXERR_MIC; + }; } if (rxsp->status11 & AR_KeyMiss) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h index e203b51e968..cbf60b090bd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h @@ -92,7 +92,8 @@ struct ar9003_txc { u32 ctl20; /* DMA control 20 */ u32 ctl21; /* DMA control 21 */ u32 ctl22; /* DMA control 22 */ - u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */ + u32 ctl23; /* DMA control 23 */ + u32 pad[8]; /* pad to cache line (128 bytes/32 dwords) */ } __packed __aligned(4); struct ar9003_txs { diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 709520c6835..3cac293a284 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -16,14 +16,12 @@ #include <linux/export.h> #include "hw.h" +#include "hw-ops.h" #include "ar9003_phy.h" #include "ar9003_mci.h" static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah) { - if (!AR_SREV_9462_20(ah)) - return; - REG_RMW_FIELD(ah, AR_MCI_COMMAND2, AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1); udelay(1); @@ -37,13 +35,10 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address, struct ath_common *common = ath9k_hw_common(ah); while (time_out) { - if (REG_READ(ah, address) & bit_position) { - REG_WRITE(ah, address, bit_position); if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) { - if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) ar9003_mci_reset_req_wakeup(ah); @@ -81,25 +76,19 @@ static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address, return time_out; } -void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done) +static void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done) { u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00}; - if (!ATH9K_HW_CAP_MCI) - return; - ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16, wait_done, false); udelay(5); } -void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done) +static void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done) { u32 payload = 0x00000000; - if (!ATH9K_HW_CAP_MCI) - return; - ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1, wait_done, false); } @@ -111,11 +100,8 @@ static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done) udelay(5); } -void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done) +static void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done) { - if (!ATH9K_HW_CAP_MCI) - return; - ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP, NULL, 0, wait_done, false); } @@ -138,30 +124,27 @@ static void ar9003_mci_send_sys_sleeping(struct ath_hw *ah, bool wait_done) static void ar9003_mci_send_coex_version_query(struct ath_hw *ah, bool wait_done) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; if (!mci->bt_version_known && - (mci->bt_state != MCI_BT_SLEEP)) { - ath_dbg(common, MCI, "MCI Send Coex version query\n"); + (mci->bt_state != MCI_BT_SLEEP)) { MCI_GPM_SET_TYPE_OPCODE(payload, - MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY); + MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_VERSION_QUERY); ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, - wait_done, true); + wait_done, true); } } static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, - bool wait_done) + bool wait_done) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; - ath_dbg(common, MCI, "MCI Send Coex version response\n"); MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, - MCI_GPM_COEX_VERSION_RESPONSE); + MCI_GPM_COEX_VERSION_RESPONSE); *(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) = mci->wlan_ver_major; *(((u8 *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) = @@ -170,15 +153,16 @@ static void ar9003_mci_send_coex_version_response(struct ath_hw *ah, } static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah, - bool wait_done) + bool wait_done) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 *payload = &mci->wlan_channels[0]; if ((mci->wlan_channels_update == true) && - (mci->bt_state != MCI_BT_SLEEP)) { + (mci->bt_state != MCI_BT_SLEEP)) { MCI_GPM_SET_TYPE_OPCODE(payload, - MCI_GPM_COEX_AGENT, MCI_GPM_COEX_WLAN_CHANNELS); + MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_WLAN_CHANNELS); ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); @@ -188,7 +172,6 @@ static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah, static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, bool wait_done, u8 query_type) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; bool query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO | @@ -196,25 +179,19 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, if (mci->bt_state != MCI_BT_SLEEP) { - ath_dbg(common, MCI, "MCI Send Coex BT Status Query 0x%02X\n", - query_type); - - MCI_GPM_SET_TYPE_OPCODE(payload, - MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY); + MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_STATUS_QUERY); *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; + /* * If bt_status_query message is not sent successfully, * then need_flush_btinfo should be set again. */ if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true)) { - if (query_btinfo) { + if (query_btinfo) mci->need_flush_btinfo = true; - - ath_dbg(common, MCI, - "MCI send bt_status_query fail, set flush flag again\n"); - } } if (query_btinfo) @@ -222,21 +199,14 @@ static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah, } } -void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, - bool wait_done) +static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, + bool wait_done) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; - if (!ATH9K_HW_CAP_MCI) - return; - - ath_dbg(common, MCI, "MCI Send Coex %s BT GPM\n", - (halt) ? "halt" : "unhalt"); - - MCI_GPM_SET_TYPE_OPCODE(payload, - MCI_GPM_COEX_AGENT, MCI_GPM_COEX_HALT_BT_GPM); + MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_HALT_BT_GPM); if (halt) { mci->query_bt = true; @@ -252,7 +222,6 @@ void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true); } - static void ar9003_mci_prep_interface(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -269,30 +238,14 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, REG_READ(ah, AR_MCI_INTERRUPT_RAW)); - /* Remote Reset */ - ath_dbg(common, MCI, "MCI Reset sequence start\n"); - ath_dbg(common, MCI, "MCI send REMOTE_RESET\n"); ar9003_mci_remote_reset(ah, true); - - /* - * This delay is required for the reset delay worst case value 255 in - * MCI_COMMAND2 register - */ - - if (AR_SREV_9462_10(ah)) - udelay(252); - - ath_dbg(common, MCI, "MCI Send REQ_WAKE to remoter(BT)\n"); ar9003_mci_send_req_wake(ah, true); if (ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { + AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) { - ath_dbg(common, MCI, "MCI SYS_WAKING from remote(BT)\n"); mci->bt_state = MCI_BT_AWAKE; - if (AR_SREV_9462_10(ah)) - udelay(10); /* * we don't need to send more remote_reset at this moment. * If BT receive first remote_reset, then BT HW will @@ -309,11 +262,6 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) * Similarly, if in any case, WLAN can receive BT's sys_waking, * that means WLAN's RX is also fine. */ - - /* Send SYS_WAKING to BT */ - - ath_dbg(common, MCI, "MCI send SW SYS_WAKING to remote BT\n"); - ar9003_mci_send_sys_waking(ah, true); udelay(10); @@ -321,7 +269,6 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) * Set BT priority interrupt value to be 0xff to * avoid having too many BT PRIORITY interrupts. */ - REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); @@ -339,77 +286,70 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah) REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); - if (AR_SREV_9462_10(ah) || mci->is_2g) { - /* Send LNA_TRANS */ - ath_dbg(common, MCI, "MCI send LNA_TRANS to BT\n"); + if (mci->is_2g) { ar9003_mci_send_lna_transfer(ah, true); udelay(5); } - if (AR_SREV_9462_10(ah) || (mci->is_2g && - !mci->update_2g5g)) { + if ((mci->is_2g && !mci->update_2g5g)) { if (ar9003_mci_wait_for_interrupt(ah, - AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, - mci_timeout)) + AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, + mci_timeout)) ath_dbg(common, MCI, "MCI WLAN has control over the LNA & BT obeys it\n"); else ath_dbg(common, MCI, "MCI BT didn't respond to LNA_TRANS\n"); } - - if (AR_SREV_9462_10(ah)) { - /* Send another remote_reset to deassert BT clk_req. */ - ath_dbg(common, MCI, - "MCI another remote_reset to deassert clk_req\n"); - ar9003_mci_remote_reset(ah, true); - udelay(252); - } } /* Clear the extra redundant SYS_WAKING from BT */ if ((mci->bt_state == MCI_BT_AWAKE) && (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && - (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { - - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING); - REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, - AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); + (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) { + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING); + REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, + AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); } REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en); } -void ar9003_mci_disable_interrupt(struct ath_hw *ah) +void ar9003_mci_set_full_sleep(struct ath_hw *ah) { - if (!ATH9K_HW_CAP_MCI) - return; + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && + (mci->bt_state != MCI_BT_SLEEP) && + !mci->halted_bt_gpm) { + ar9003_mci_send_coex_halt_bt_gpm(ah, true, true); + } + + mci->ready = false; + REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); +} + +static void ar9003_mci_disable_interrupt(struct ath_hw *ah) +{ REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); } -void ar9003_mci_enable_interrupt(struct ath_hw *ah) +static void ar9003_mci_enable_interrupt(struct ath_hw *ah) { - if (!ATH9K_HW_CAP_MCI) - return; - REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT); REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, AR_MCI_INTERRUPT_RX_MSG_DEFAULT); } -bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints) +static bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints) { u32 intr; - if (!ATH9K_HW_CAP_MCI) - return false; - intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); return ((intr & ints) == ints); } @@ -419,9 +359,6 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (!ATH9K_HW_CAP_MCI) - return; - *raw_intr = mci->raw_intr; *rx_msg_intr = mci->rx_msg_intr; @@ -431,12 +368,34 @@ void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, } EXPORT_SYMBOL(ar9003_mci_get_interrupt); -void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g) +void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) { + struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 raw_intr, rx_msg_intr; - if (!ATH9K_HW_CAP_MCI) - return; + rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); + raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW); + + if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) { + ath_dbg(common, MCI, + "MCI gets 0xdeadbeef during int processing\n"); + } else { + mci->rx_msg_intr |= rx_msg_intr; + mci->raw_intr |= raw_intr; + *masked |= ATH9K_INT_MCI; + + if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) + mci->cont_status = REG_READ(ah, AR_MCI_CONT_STATUS); + + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr); + REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr); + } +} + +static void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g) +{ + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; if (!mci->update_2g5g && (mci->is_2g != is_2g)) @@ -447,7 +406,6 @@ void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g) static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 *payload; u32 recv_type, offset; @@ -460,10 +418,8 @@ static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index) payload = (u32 *)(mci->gpm_buf + offset); recv_type = MCI_GPM_TYPE(payload); - if (recv_type == MCI_GPM_RSVD_PATTERN) { - ath_dbg(common, MCI, "MCI Skip RSVD GPM\n"); + if (recv_type == MCI_GPM_RSVD_PATTERN) return false; - } return true; } @@ -471,42 +427,31 @@ static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index) static void ar9003_mci_observation_set_up(struct ath_hw *ah) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) { - ath9k_hw_cfg_output(ah, 3, - AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA); + if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) { + ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA); ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK); ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA); ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK); - } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) { - ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX); ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX); ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX); ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX); ath9k_hw_cfg_output(ah, 5, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) { - ath9k_hw_cfg_output(ah, 3, AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX); ath9k_hw_cfg_output(ah, 2, AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX); ath9k_hw_cfg_output(ah, 1, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA); ath9k_hw_cfg_output(ah, 0, AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK); - } else return; REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); - if (AR_SREV_9462_20_OR_LATER(ah)) { - REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, - AR_GLB_DS_JTAG_DISABLE, 1); - REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, - AR_GLB_WLAN_UART_INTF_EN, 0); - REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL, - ATH_MCI_CONFIG_MCI_OBS_GPIO); - } + REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1); + REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0); + REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL, ATH_MCI_CONFIG_MCI_OBS_GPIO); REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0); REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1); @@ -520,13 +465,12 @@ static void ar9003_mci_observation_set_up(struct ath_hw *ah) } static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done, - u8 opcode, u32 bt_flags) + u8 opcode, u32 bt_flags) { - struct ath_common *common = ath9k_hw_common(ah); u32 pld[4] = {0, 0, 0, 0}; - MCI_GPM_SET_TYPE_OPCODE(pld, - MCI_GPM_COEX_AGENT, MCI_GPM_COEX_BT_UPDATE_FLAGS); + MCI_GPM_SET_TYPE_OPCODE(pld, MCI_GPM_COEX_AGENT, + MCI_GPM_COEX_BT_UPDATE_FLAGS); *(((u8 *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP) = opcode; *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF; @@ -534,32 +478,360 @@ static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done, *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF; *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF; - ath_dbg(common, MCI, - "MCI BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n", - opcode == MCI_GPM_COEX_BT_FLAGS_READ ? "READ" : - opcode == MCI_GPM_COEX_BT_FLAGS_SET ? "SET" : "CLEAR", - bt_flags); - return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, - wait_done, true); + wait_done, true); } -void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, - bool is_full_sleep) +static void ar9003_mci_sync_bt_state(struct ath_hw *ah) +{ + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 cur_bt_state; + + cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); + + if (mci->bt_state != cur_bt_state) + mci->bt_state = cur_bt_state; + + if (mci->bt_state != MCI_BT_SLEEP) { + + ar9003_mci_send_coex_version_query(ah, true); + ar9003_mci_send_coex_wlan_channels(ah, true); + + if (mci->unhalt_bt_gpm == true) + ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); + } +} + +void ar9003_mci_check_bt(struct ath_hw *ah) +{ + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; + + if (!mci_hw->ready) + return; + + /* + * check BT state again to make + * sure it's not changed. + */ + ar9003_mci_sync_bt_state(ah); + ar9003_mci_2g5g_switch(ah, true); + + if ((mci_hw->bt_state == MCI_BT_AWAKE) && + (mci_hw->query_bt == true)) { + mci_hw->need_flush_btinfo = true; + } +} + +static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type, + u8 gpm_opcode, u32 *p_gpm) { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 regval, thresh; + u8 *p_data = (u8 *) p_gpm; - if (!ATH9K_HW_CAP_MCI) + if (gpm_type != MCI_GPM_COEX_AGENT) return; - ath_dbg(common, MCI, "MCI full_sleep = %d, is_2g = %d\n", - is_full_sleep, is_2g); + switch (gpm_opcode) { + case MCI_GPM_COEX_VERSION_QUERY: + ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n"); + ar9003_mci_send_coex_version_response(ah, true); + break; + case MCI_GPM_COEX_VERSION_RESPONSE: + ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n"); + mci->bt_ver_major = + *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION); + mci->bt_ver_minor = + *(p_data + MCI_GPM_COEX_B_MINOR_VERSION); + mci->bt_version_known = true; + ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n", + mci->bt_ver_major, mci->bt_ver_minor); + break; + case MCI_GPM_COEX_STATUS_QUERY: + ath_dbg(common, MCI, + "MCI Recv GPM COEX Status Query = 0x%02X\n", + *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)); + mci->wlan_channels_update = true; + ar9003_mci_send_coex_wlan_channels(ah, true); + break; + case MCI_GPM_COEX_BT_PROFILE_INFO: + mci->query_bt = true; + ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n"); + break; + case MCI_GPM_COEX_BT_STATUS_UPDATE: + mci->query_bt = true; + ath_dbg(common, MCI, + "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n", + *(p_gpm + 3)); + break; + default: + break; + } +} + +static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, + u8 gpm_opcode, int time_out) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 *p_gpm = NULL, mismatch = 0, more_data; + u32 offset; + u8 recv_type = 0, recv_opcode = 0; + bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE); + + more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE; + + while (time_out > 0) { + if (p_gpm) { + MCI_GPM_RECYCLE(p_gpm); + p_gpm = NULL; + } + + if (more_data != MCI_GPM_MORE) + time_out = ar9003_mci_wait_for_interrupt(ah, + AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_GPM, + time_out); + + if (!time_out) + break; + + offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, + &more_data); + + if (offset == MCI_GPM_INVALID) + continue; + + p_gpm = (u32 *) (mci->gpm_buf + offset); + recv_type = MCI_GPM_TYPE(p_gpm); + recv_opcode = MCI_GPM_OPCODE(p_gpm); + + if (MCI_GPM_IS_CAL_TYPE(recv_type)) { + if (recv_type == gpm_type) { + if ((gpm_type == MCI_GPM_BT_CAL_DONE) && + !b_is_bt_cal_done) { + gpm_type = MCI_GPM_BT_CAL_GRANT; + continue; + } + break; + } + } else if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) { + break; + } + + /* + * check if it's cal_grant + * + * When we're waiting for cal_grant in reset routine, + * it's possible that BT sends out cal_request at the + * same time. Since BT's calibration doesn't happen + * that often, we'll let BT completes calibration then + * we continue to wait for cal_grant from BT. + * Orginal: Wait BT_CAL_GRANT. + * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait + * BT_CAL_DONE -> Wait BT_CAL_GRANT. + */ + + if ((gpm_type == MCI_GPM_BT_CAL_GRANT) && + (recv_type == MCI_GPM_BT_CAL_REQ)) { + + u32 payload[4] = {0, 0, 0, 0}; + + gpm_type = MCI_GPM_BT_CAL_DONE; + MCI_GPM_SET_CAL_TYPE(payload, + MCI_GPM_WLAN_CAL_GRANT); + ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, + false, false); + continue; + } else { + ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n", + *(p_gpm + 1)); + mismatch++; + ar9003_mci_process_gpm_extra(ah, recv_type, + recv_opcode, p_gpm); + } + } + + if (p_gpm) { + MCI_GPM_RECYCLE(p_gpm); + p_gpm = NULL; + } + + if (time_out <= 0) + time_out = 0; + + while (more_data == MCI_GPM_MORE) { + offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, + &more_data); + if (offset == MCI_GPM_INVALID) + break; + + p_gpm = (u32 *) (mci->gpm_buf + offset); + recv_type = MCI_GPM_TYPE(p_gpm); + recv_opcode = MCI_GPM_OPCODE(p_gpm); + + if (!MCI_GPM_IS_CAL_TYPE(recv_type)) + ar9003_mci_process_gpm_extra(ah, recv_type, + recv_opcode, p_gpm); + + MCI_GPM_RECYCLE(p_gpm); + } + + return time_out; +} + +bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; + u32 payload[4] = {0, 0, 0, 0}; + + ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan)); + + if (mci_hw->bt_state != MCI_BT_CAL_START) + return false; + + mci_hw->bt_state = MCI_BT_CAL; + + /* + * MCI FIX: disable mci interrupt here. This is to avoid + * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and + * lead to mci_intr reentry. + */ + ar9003_mci_disable_interrupt(ah); + + MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT); + ar9003_mci_send_message(ah, MCI_GPM, 0, payload, + 16, true, false); + + /* Wait BT calibration to be completed for 25ms */ + + if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, + 0, 25000)) + ath_dbg(common, MCI, "MCI BT_CAL_DONE received\n"); + else + ath_dbg(common, MCI, + "MCI BT_CAL_DONE not received\n"); + + mci_hw->bt_state = MCI_BT_AWAKE; + /* MCI FIX: enable mci interrupt here */ + ar9003_mci_enable_interrupt(ah); + + return true; +} + +int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata) +{ + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; + + if (!mci_hw->ready) + return 0; + + if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP)) + goto exit; + + if (ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || + ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) { + + /* + * BT is sleeping. Check if BT wakes up during + * WLAN calibration. If BT wakes up during + * WLAN calibration, need to go through all + * message exchanges again and recal. + */ + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | + AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); + + ar9003_mci_remote_reset(ah, true); + ar9003_mci_send_sys_waking(ah, true); + udelay(1); + + if (IS_CHAN_2GHZ(chan)) + ar9003_mci_send_lna_transfer(ah, true); + + mci_hw->bt_state = MCI_BT_AWAKE; + + if (caldata) { + caldata->done_txiqcal_once = false; + caldata->done_txclcal_once = false; + caldata->rtt_hist.num_readings = 0; + } + + if (!ath9k_hw_init_cal(ah, chan)) + return -EIO; + + } +exit: + ar9003_mci_enable_interrupt(ah); + return 0; +} + +static void ar9003_mci_mute_bt(struct ath_hw *ah) +{ + /* disable all MCI messages */ + REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff); + REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); + + /* wait pending HW messages to flush out */ + udelay(10); /* - * GPM buffer and scheduling message buffer are not allocated + * Send LNA_TAKE and SYS_SLEEPING when + * 1. reset not after resuming from full sleep + * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment */ + ar9003_mci_send_lna_take(ah, true); + + udelay(5); + + ar9003_mci_send_sys_sleeping(ah, true); +} + +static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) +{ + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 thresh; + + if (enable) { + REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, + AR_MCI_SCHD_TABLE_2_HW_BASED, 1); + REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, + AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); + + if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { + thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH); + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_AGGR_THRESH, thresh); + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); + } else { + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); + } + + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); + } else { + REG_CLR_BIT(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); + } +} + +void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep) +{ + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + u32 regval; + + ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n", + is_full_sleep, is_2g); if (!mci->gpm_addr && !mci->sched_addr) { ath_dbg(common, MCI, @@ -568,7 +840,7 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, } if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { - ath_dbg(common, MCI, "MCI it's deadbeef, quit mci_reset\n"); + ath_dbg(common, MCI, "BTCOEX control register is dead\n"); return; } @@ -592,49 +864,23 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - if (is_2g && (AR_SREV_9462_20(ah)) && - !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { - - regval |= SM(1, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - ath_dbg(common, MCI, "MCI sched one step look ahead\n"); - - if (!(mci->config & - ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) { - - thresh = MS(mci->config, - ATH_MCI_CONFIG_AGGR_THRESH); - thresh &= 7; - regval |= SM(1, - AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN); - regval |= SM(thresh, AR_BTCOEX_CTRL_AGGR_THRESH); - - REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, - AR_MCI_SCHD_TABLE_2_HW_BASED, 1); - REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, - AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); - - } else - ath_dbg(common, MCI, "MCI sched aggr thresh: off\n"); - } else - ath_dbg(common, MCI, "MCI SCHED one step look ahead off\n"); - - if (AR_SREV_9462_10(ah)) - regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10); - REG_WRITE(ah, AR_BTCOEX_CTRL, regval); - if (AR_SREV_9462_20(ah)) { - REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, - AR_BTCOEX_CTRL_SPDT_ENABLE); - REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3, - AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20); - } + if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) + ar9003_mci_osla_setup(ah, true); + else + ar9003_mci_osla_setup(ah, false); + + REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, + AR_BTCOEX_CTRL_SPDT_ENABLE); + REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3, + AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20); REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 1); REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); - thresh = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV); - REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, thresh); + regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV); + REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval); REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN); /* Resetting the Rx and Tx paths of MCI */ @@ -659,15 +905,15 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, REG_WRITE(ah, AR_MCI_COMMAND2, regval); ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); + REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM))); REG_CLR_BIT(ah, AR_MCI_TX_CTRL, - AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); + AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); - if (AR_SREV_9462_20_OR_LATER(ah)) - ar9003_mci_observation_set_up(ah); + ar9003_mci_observation_set_up(ah); mci->ready = true; ar9003_mci_prep_interface(ah); @@ -676,79 +922,28 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, ar9003_mci_enable_interrupt(ah); } -void ar9003_mci_mute_bt(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - - if (!ATH9K_HW_CAP_MCI) - return; - - /* disable all MCI messages */ - REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff); - REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff); - REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); - - /* wait pending HW messages to flush out */ - udelay(10); - - /* - * Send LNA_TAKE and SYS_SLEEPING when - * 1. reset not after resuming from full sleep - * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment - */ - - ath_dbg(common, MCI, "MCI Send LNA take\n"); - ar9003_mci_send_lna_take(ah, true); - - udelay(5); - - ath_dbg(common, MCI, "MCI Send sys sleeping\n"); - ar9003_mci_send_sys_sleeping(ah, true); -} - -void ar9003_mci_sync_bt_state(struct ath_hw *ah) +void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) { - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 cur_bt_state; - - if (!ATH9K_HW_CAP_MCI) - return; + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; - cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); + ar9003_mci_disable_interrupt(ah); - if (mci->bt_state != cur_bt_state) { - ath_dbg(common, MCI, - "MCI BT state mismatches. old: %d, new: %d\n", - mci->bt_state, cur_bt_state); - mci->bt_state = cur_bt_state; + if (mci_hw->ready && !save_fullsleep) { + ar9003_mci_mute_bt(ah); + udelay(20); + REG_WRITE(ah, AR_BTCOEX_CTRL, 0); } - if (mci->bt_state != MCI_BT_SLEEP) { - - ar9003_mci_send_coex_version_query(ah, true); - ar9003_mci_send_coex_wlan_channels(ah, true); - - if (mci->unhalt_bt_gpm == true) { - ath_dbg(common, MCI, "MCI unhalt BT GPM\n"); - ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); - } - } + mci_hw->bt_state = MCI_BT_SLEEP; + mci_hw->ready = false; } static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 new_flags, to_set, to_clear; - if (AR_SREV_9462_20(ah) && - mci->update_2g5g && - (mci->bt_state != MCI_BT_SLEEP)) { - + if (mci->update_2g5g && (mci->bt_state != MCI_BT_SLEEP)) { if (mci->is_2g) { new_flags = MCI_2G_FLAGS; to_clear = MCI_2G_FLAGS_CLEAR_MASK; @@ -759,44 +954,23 @@ static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done) to_set = MCI_5G_FLAGS_SET_MASK; } - ath_dbg(common, MCI, - "MCI BT_MCI_FLAGS: %s 0x%08x clr=0x%08x, set=0x%08x\n", - mci->is_2g ? "2G" : "5G", new_flags, to_clear, to_set); - if (to_clear) ar9003_mci_send_coex_bt_flags(ah, wait_done, - MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear); - + MCI_GPM_COEX_BT_FLAGS_CLEAR, + to_clear); if (to_set) ar9003_mci_send_coex_bt_flags(ah, wait_done, - MCI_GPM_COEX_BT_FLAGS_SET, to_set); + MCI_GPM_COEX_BT_FLAGS_SET, + to_set); } - - if (AR_SREV_9462_10(ah) && (mci->bt_state != MCI_BT_SLEEP)) - mci->update_2g5g = false; } static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, u32 *payload, bool queue) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u8 type, opcode; - if (queue) { - - if (payload) - ath_dbg(common, MCI, - "MCI ERROR: Send fail: %02x: %02x %02x %02x\n", - header, - *(((u8 *)payload) + 4), - *(((u8 *)payload) + 5), - *(((u8 *)payload) + 6)); - else - ath_dbg(common, MCI, "MCI ERROR: Send fail: %02x\n", - header); - } - /* check if the message is to be queued */ if (header != MCI_GPM) return; @@ -809,64 +983,29 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, switch (opcode) { case MCI_GPM_COEX_BT_UPDATE_FLAGS: - - if (AR_SREV_9462_10(ah)) - break; - if (*(((u8 *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) == - MCI_GPM_COEX_BT_FLAGS_READ) + MCI_GPM_COEX_BT_FLAGS_READ) break; mci->update_2g5g = queue; - if (queue) - ath_dbg(common, MCI, - "MCI BT_MCI_FLAGS: 2G5G status <queued> %s\n", - mci->is_2g ? "2G" : "5G"); - else - ath_dbg(common, MCI, - "MCI BT_MCI_FLAGS: 2G5G status <sent> %s\n", - mci->is_2g ? "2G" : "5G"); - break; - case MCI_GPM_COEX_WLAN_CHANNELS: - mci->wlan_channels_update = queue; - if (queue) - ath_dbg(common, MCI, "MCI WLAN channel map <queued>\n"); - else - ath_dbg(common, MCI, "MCI WLAN channel map <sent>\n"); break; - case MCI_GPM_COEX_HALT_BT_GPM: - if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) == - MCI_GPM_COEX_BT_GPM_UNHALT) { - + MCI_GPM_COEX_BT_GPM_UNHALT) { mci->unhalt_bt_gpm = queue; - if (queue) - ath_dbg(common, MCI, - "MCI UNHALT BT GPM <queued>\n"); - else { + if (!queue) mci->halted_bt_gpm = false; - ath_dbg(common, MCI, - "MCI UNHALT BT GPM <sent>\n"); - } } if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) == MCI_GPM_COEX_BT_GPM_HALT) { mci->halted_bt_gpm = !queue; - - if (queue) - ath_dbg(common, MCI, - "MCI HALT BT GPM <not sent>\n"); - else - ath_dbg(common, MCI, - "MCI UNHALT BT GPM <sent>\n"); } break; @@ -877,46 +1016,33 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (!ATH9K_HW_CAP_MCI) - return; - if (mci->update_2g5g) { if (mci->is_2g) { - ar9003_mci_send_2g5g_status(ah, true); - ath_dbg(common, MCI, "MCI Send LNA trans\n"); ar9003_mci_send_lna_transfer(ah, true); udelay(5); REG_CLR_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); + REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, + AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); - if (AR_SREV_9462_20(ah)) { - REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL, - AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); - if (!(mci->config & - ATH_MCI_CONFIG_DISABLE_OSLA)) { - REG_SET_BIT(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - } + if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) { + REG_SET_BIT(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); } } else { - ath_dbg(common, MCI, "MCI Send LNA take\n"); ar9003_mci_send_lna_take(ah, true); udelay(5); REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); - - if (AR_SREV_9462_20(ah)) { - REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, - AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); - REG_CLR_BIT(ah, AR_BTCOEX_CTRL, - AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - } + REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, + AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); + REG_CLR_BIT(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); ar9003_mci_send_2g5g_status(ah, true); } @@ -934,28 +1060,19 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, u32 saved_mci_int_en; int i; - if (!ATH9K_HW_CAP_MCI) - return false; - saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN); regval = REG_READ(ah, AR_BTCOEX_CTRL); if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) { - ath_dbg(common, MCI, "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n", - header, - (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0); - + header, (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0); ar9003_mci_queue_unsent_gpm(ah, header, payload, true); return false; - } else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) { - ath_dbg(common, MCI, "MCI Don't send message 0x%x. BT is in sleep state\n", header); - ar9003_mci_queue_unsent_gpm(ah, header, payload, true); return false; } @@ -983,7 +1100,7 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, if (wait_done && !(ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW, - AR_MCI_INTERRUPT_SW_MSG_DONE, 500))) + AR_MCI_INTERRUPT_SW_MSG_DONE, 500))) ar9003_mci_queue_unsent_gpm(ah, header, payload, true); else { ar9003_mci_queue_unsent_gpm(ah, header, payload, false); @@ -997,220 +1114,64 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, } EXPORT_SYMBOL(ar9003_mci_send_message); -void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, - u16 len, u32 sched_addr) +void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable) { - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr)); + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; + u32 pld[4] = {0, 0, 0, 0}; - if (!ATH9K_HW_CAP_MCI) + if ((mci_hw->bt_state != MCI_BT_AWAKE) || + (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) return; - mci->gpm_addr = gpm_addr; - mci->gpm_buf = gpm_buf; - mci->gpm_len = len; - mci->sched_addr = sched_addr; - mci->sched_buf = sched_buf; + MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ); + pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++; - ar9003_mci_reset(ah, true, true, true); + ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); + + if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) { + ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n"); + } else { + is_reusable = false; + ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n"); + } } -EXPORT_SYMBOL(ar9003_mci_setup); -void ar9003_mci_cleanup(struct ath_hw *ah) +void ar9003_mci_init_cal_done(struct ath_hw *ah) { - struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; + u32 pld[4] = {0, 0, 0, 0}; - if (!ATH9K_HW_CAP_MCI) + if ((mci_hw->bt_state != MCI_BT_AWAKE) || + (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL)) return; - /* Turn off MCI and Jupiter mode. */ - REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00); - ath_dbg(common, MCI, "MCI ar9003_mci_cleanup\n"); - ar9003_mci_disable_interrupt(ah); + MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE); + pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++; + ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); } -EXPORT_SYMBOL(ar9003_mci_cleanup); -static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type, - u8 gpm_opcode, u32 *p_gpm) +void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, + u16 len, u32 sched_addr) { - struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u8 *p_data = (u8 *) p_gpm; - if (gpm_type != MCI_GPM_COEX_AGENT) - return; + mci->gpm_addr = gpm_addr; + mci->gpm_buf = gpm_buf; + mci->gpm_len = len; + mci->sched_addr = sched_addr; - switch (gpm_opcode) { - case MCI_GPM_COEX_VERSION_QUERY: - ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n"); - ar9003_mci_send_coex_version_response(ah, true); - break; - case MCI_GPM_COEX_VERSION_RESPONSE: - ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n"); - mci->bt_ver_major = - *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION); - mci->bt_ver_minor = - *(p_data + MCI_GPM_COEX_B_MINOR_VERSION); - mci->bt_version_known = true; - ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n", - mci->bt_ver_major, mci->bt_ver_minor); - break; - case MCI_GPM_COEX_STATUS_QUERY: - ath_dbg(common, MCI, - "MCI Recv GPM COEX Status Query = 0x%02X\n", - *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)); - mci->wlan_channels_update = true; - ar9003_mci_send_coex_wlan_channels(ah, true); - break; - case MCI_GPM_COEX_BT_PROFILE_INFO: - mci->query_bt = true; - ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n"); - break; - case MCI_GPM_COEX_BT_STATUS_UPDATE: - mci->query_bt = true; - ath_dbg(common, MCI, - "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n", - *(p_gpm + 3)); - break; - default: - break; - } + ar9003_mci_reset(ah, true, true, true); } +EXPORT_SYMBOL(ar9003_mci_setup); -u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, - u8 gpm_opcode, int time_out) +void ar9003_mci_cleanup(struct ath_hw *ah) { - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 *p_gpm = NULL, mismatch = 0, more_data; - u32 offset; - u8 recv_type = 0, recv_opcode = 0; - bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE); - - if (!ATH9K_HW_CAP_MCI) - return 0; - - more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE; - - while (time_out > 0) { - if (p_gpm) { - MCI_GPM_RECYCLE(p_gpm); - p_gpm = NULL; - } - - if (more_data != MCI_GPM_MORE) - time_out = ar9003_mci_wait_for_interrupt(ah, - AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_GPM, - time_out); - - if (!time_out) - break; - - offset = ar9003_mci_state(ah, - MCI_STATE_NEXT_GPM_OFFSET, &more_data); - - if (offset == MCI_GPM_INVALID) - continue; - - p_gpm = (u32 *) (mci->gpm_buf + offset); - recv_type = MCI_GPM_TYPE(p_gpm); - recv_opcode = MCI_GPM_OPCODE(p_gpm); - - if (MCI_GPM_IS_CAL_TYPE(recv_type)) { - - if (recv_type == gpm_type) { - - if ((gpm_type == MCI_GPM_BT_CAL_DONE) && - !b_is_bt_cal_done) { - gpm_type = MCI_GPM_BT_CAL_GRANT; - ath_dbg(common, MCI, - "MCI Recv BT_CAL_DONE wait BT_CAL_GRANT\n"); - continue; - } - - break; - } - } else if ((recv_type == gpm_type) && - (recv_opcode == gpm_opcode)) - break; - - /* not expected message */ - - /* - * check if it's cal_grant - * - * When we're waiting for cal_grant in reset routine, - * it's possible that BT sends out cal_request at the - * same time. Since BT's calibration doesn't happen - * that often, we'll let BT completes calibration then - * we continue to wait for cal_grant from BT. - * Orginal: Wait BT_CAL_GRANT. - * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait - * BT_CAL_DONE -> Wait BT_CAL_GRANT. - */ - - if ((gpm_type == MCI_GPM_BT_CAL_GRANT) && - (recv_type == MCI_GPM_BT_CAL_REQ)) { - - u32 payload[4] = {0, 0, 0, 0}; - - gpm_type = MCI_GPM_BT_CAL_DONE; - ath_dbg(common, MCI, - "MCI Rcv BT_CAL_REQ, send WLAN_CAL_GRANT\n"); - - MCI_GPM_SET_CAL_TYPE(payload, - MCI_GPM_WLAN_CAL_GRANT); - - ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, - false, false); - - ath_dbg(common, MCI, "MCI now wait for BT_CAL_DONE\n"); - - continue; - } else { - ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n", - *(p_gpm + 1)); - mismatch++; - ar9003_mci_process_gpm_extra(ah, recv_type, - recv_opcode, p_gpm); - } - } - if (p_gpm) { - MCI_GPM_RECYCLE(p_gpm); - p_gpm = NULL; - } - - if (time_out <= 0) { - time_out = 0; - ath_dbg(common, MCI, - "MCI GPM received timeout, mismatch = %d\n", mismatch); - } else - ath_dbg(common, MCI, "MCI Receive GPM type=0x%x, code=0x%x\n", - gpm_type, gpm_opcode); - - while (more_data == MCI_GPM_MORE) { - - ath_dbg(common, MCI, "MCI discard remaining GPM\n"); - offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, - &more_data); - - if (offset == MCI_GPM_INVALID) - break; - - p_gpm = (u32 *) (mci->gpm_buf + offset); - recv_type = MCI_GPM_TYPE(p_gpm); - recv_opcode = MCI_GPM_OPCODE(p_gpm); - - if (!MCI_GPM_IS_CAL_TYPE(recv_type)) - ar9003_mci_process_gpm_extra(ah, recv_type, - recv_opcode, p_gpm); - - MCI_GPM_RECYCLE(p_gpm); - } - - return time_out; + /* Turn off MCI and Jupiter mode. */ + REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00); + ar9003_mci_disable_interrupt(ah); } +EXPORT_SYMBOL(ar9003_mci_cleanup); u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) { @@ -1219,13 +1180,9 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) u32 value = 0, more_gpm = 0, gpm_ptr; u8 query_type; - if (!ATH9K_HW_CAP_MCI) - return 0; - switch (state_type) { case MCI_STATE_ENABLE: if (mci->ready) { - value = REG_READ(ah, AR_BTCOEX_CTRL); if ((value == 0xdeadbeef) || (value == 0xffffffff)) @@ -1235,7 +1192,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) break; case MCI_STATE_INIT_GPM_OFFSET: value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - ath_dbg(common, MCI, "MCI GPM initial WRITE_PTR=%d\n", value); mci->gpm_idx = value; break; case MCI_STATE_NEXT_GPM_OFFSET: @@ -1258,32 +1214,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) if (value == 0) value = mci->gpm_len - 1; else if (value >= mci->gpm_len) { - if (value != 0xFFFF) { + if (value != 0xFFFF) value = 0; - ath_dbg(common, MCI, - "MCI GPM offset out of range\n"); - } - } else + } else { value--; + } if (value == 0xFFFF) { value = MCI_GPM_INVALID; more_gpm = MCI_GPM_NOMORE; - ath_dbg(common, MCI, - "MCI GPM ptr invalid @ptr=%d, offset=%d, more=GPM_NOMORE\n", - gpm_ptr, value); } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) { - if (gpm_ptr == mci->gpm_idx) { value = MCI_GPM_INVALID; more_gpm = MCI_GPM_NOMORE; - - ath_dbg(common, MCI, - "MCI GPM message not available @ptr=%d, @offset=%d, more=GPM_NOMORE\n", - gpm_ptr, value); } else { for (;;) { - u32 temp_index; /* skip reserved GPM if any */ @@ -1300,13 +1245,8 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) mci->gpm_len) mci->gpm_idx = 0; - ath_dbg(common, MCI, - "MCI GPM message got ptr=%d, @offset=%d, more=%d\n", - gpm_ptr, temp_index, - (more_gpm == MCI_GPM_MORE)); - if (ar9003_mci_is_gpm_valid(ah, - temp_index)) { + temp_index)) { value = temp_index; break; } @@ -1331,79 +1271,59 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) /* Make it in bytes */ value <<= 4; break; - case MCI_STATE_REMOTE_SLEEP: value = MS(REG_READ(ah, AR_MCI_RX_STATUS), AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE; break; - case MCI_STATE_CONT_RSSI_POWER: value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER); - break; - + break; case MCI_STATE_CONT_PRIORITY: value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY); break; - case MCI_STATE_CONT_TXRX: value = MS(mci->cont_status, AR_MCI_CONT_TXRX); break; - case MCI_STATE_BT: value = mci->bt_state; break; - case MCI_STATE_SET_BT_SLEEP: mci->bt_state = MCI_BT_SLEEP; break; - case MCI_STATE_SET_BT_AWAKE: mci->bt_state = MCI_BT_AWAKE; ar9003_mci_send_coex_version_query(ah, true); ar9003_mci_send_coex_wlan_channels(ah, true); - if (mci->unhalt_bt_gpm) { - - ath_dbg(common, MCI, "MCI unhalt BT GPM\n"); + if (mci->unhalt_bt_gpm) ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); - } ar9003_mci_2g5g_switch(ah, true); break; - case MCI_STATE_SET_BT_CAL_START: mci->bt_state = MCI_BT_CAL_START; break; - case MCI_STATE_SET_BT_CAL: mci->bt_state = MCI_BT_CAL; break; - case MCI_STATE_RESET_REQ_WAKE: ar9003_mci_reset_req_wakeup(ah); mci->update_2g5g = true; - if ((AR_SREV_9462_20_OR_LATER(ah)) && - (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK)) { + if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK) { /* Check if we still have control of the GPIOs */ if ((REG_READ(ah, AR_GLB_GPIO_CONTROL) & - ATH_MCI_CONFIG_MCI_OBS_GPIO) != - ATH_MCI_CONFIG_MCI_OBS_GPIO) { - - ath_dbg(common, MCI, - "MCI reconfigure observation\n"); + ATH_MCI_CONFIG_MCI_OBS_GPIO) != + ATH_MCI_CONFIG_MCI_OBS_GPIO) { ar9003_mci_observation_set_up(ah); } } break; - case MCI_STATE_SEND_WLAN_COEX_VERSION: ar9003_mci_send_coex_version_response(ah, true); break; - case MCI_STATE_SET_BT_COEX_VERSION: - if (!p_data) ath_dbg(common, MCI, "MCI Set BT Coex version with NULL data!!\n"); @@ -1415,7 +1335,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) mci->bt_ver_major, mci->bt_ver_minor); } break; - case MCI_STATE_SEND_WLAN_CHANNELS: if (p_data) { if (((mci->wlan_channels[1] & 0xffff0000) == @@ -1432,19 +1351,13 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) mci->wlan_channels_update = true; ar9003_mci_send_coex_wlan_channels(ah, true); break; - case MCI_STATE_SEND_VERSION_QUERY: ar9003_mci_send_coex_version_query(ah, true); break; - case MCI_STATE_SEND_STATUS_QUERY: - query_type = (AR_SREV_9462_10(ah)) ? - MCI_GPM_COEX_QUERY_BT_ALL_INFO : - MCI_GPM_COEX_QUERY_BT_TOPOLOGY; - + query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY; ar9003_mci_send_coex_bt_status_query(ah, true, query_type); break; - case MCI_STATE_NEED_FLUSH_BT_INFO: /* * btcoex_hw.mci.unhalt_bt_gpm means whether it's @@ -1464,28 +1377,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) mci->need_flush_btinfo = (*p_data != 0) ? true : false; break; - case MCI_STATE_RECOVER_RX: - - ath_dbg(common, MCI, "MCI hw RECOVER_RX\n"); ar9003_mci_prep_interface(ah); mci->query_bt = true; mci->need_flush_btinfo = true; ar9003_mci_send_coex_wlan_channels(ah, true); ar9003_mci_2g5g_switch(ah, true); break; - case MCI_STATE_NEED_FTP_STOMP: value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); break; - case MCI_STATE_NEED_TUNING: value = !(mci->config & ATH_MCI_CONFIG_DISABLE_TUNING); break; - default: break; - } return value; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 798da116a44..4842f6c06b8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -99,4 +99,237 @@ enum mci_gpm_coex_bt_update_flags_op { ATH_MCI_CONFIG_MCI_OBS_BT) #define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F +enum mci_message_header { /* length of payload */ + MCI_LNA_CTRL = 0x10, /* len = 0 */ + MCI_CONT_NACK = 0x20, /* len = 0 */ + MCI_CONT_INFO = 0x30, /* len = 4 */ + MCI_CONT_RST = 0x40, /* len = 0 */ + MCI_SCHD_INFO = 0x50, /* len = 16 */ + MCI_CPU_INT = 0x60, /* len = 4 */ + MCI_SYS_WAKING = 0x70, /* len = 0 */ + MCI_GPM = 0x80, /* len = 16 */ + MCI_LNA_INFO = 0x90, /* len = 1 */ + MCI_LNA_STATE = 0x94, + MCI_LNA_TAKE = 0x98, + MCI_LNA_TRANS = 0x9c, + MCI_SYS_SLEEPING = 0xa0, /* len = 0 */ + MCI_REQ_WAKE = 0xc0, /* len = 0 */ + MCI_DEBUG_16 = 0xfe, /* len = 2 */ + MCI_REMOTE_RESET = 0xff /* len = 16 */ +}; + +enum ath_mci_gpm_coex_profile_type { + MCI_GPM_COEX_PROFILE_UNKNOWN, + MCI_GPM_COEX_PROFILE_RFCOMM, + MCI_GPM_COEX_PROFILE_A2DP, + MCI_GPM_COEX_PROFILE_HID, + MCI_GPM_COEX_PROFILE_BNEP, + MCI_GPM_COEX_PROFILE_VOICE, + MCI_GPM_COEX_PROFILE_MAX +}; + +/* MCI GPM/Coex opcode/type definitions */ +enum { + MCI_GPM_COEX_W_GPM_PAYLOAD = 1, + MCI_GPM_COEX_B_GPM_TYPE = 4, + MCI_GPM_COEX_B_GPM_OPCODE = 5, + /* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */ + MCI_GPM_WLAN_CAL_W_SEQUENCE = 2, + + /* MCI_GPM_COEX_VERSION_QUERY */ + /* MCI_GPM_COEX_VERSION_RESPONSE */ + MCI_GPM_COEX_B_MAJOR_VERSION = 6, + MCI_GPM_COEX_B_MINOR_VERSION = 7, + /* MCI_GPM_COEX_STATUS_QUERY */ + MCI_GPM_COEX_B_BT_BITMAP = 6, + MCI_GPM_COEX_B_WLAN_BITMAP = 7, + /* MCI_GPM_COEX_HALT_BT_GPM */ + MCI_GPM_COEX_B_HALT_STATE = 6, + /* MCI_GPM_COEX_WLAN_CHANNELS */ + MCI_GPM_COEX_B_CHANNEL_MAP = 6, + /* MCI_GPM_COEX_BT_PROFILE_INFO */ + MCI_GPM_COEX_B_PROFILE_TYPE = 6, + MCI_GPM_COEX_B_PROFILE_LINKID = 7, + MCI_GPM_COEX_B_PROFILE_STATE = 8, + MCI_GPM_COEX_B_PROFILE_ROLE = 9, + MCI_GPM_COEX_B_PROFILE_RATE = 10, + MCI_GPM_COEX_B_PROFILE_VOTYPE = 11, + MCI_GPM_COEX_H_PROFILE_T = 12, + MCI_GPM_COEX_B_PROFILE_W = 14, + MCI_GPM_COEX_B_PROFILE_A = 15, + /* MCI_GPM_COEX_BT_STATUS_UPDATE */ + MCI_GPM_COEX_B_STATUS_TYPE = 6, + MCI_GPM_COEX_B_STATUS_LINKID = 7, + MCI_GPM_COEX_B_STATUS_STATE = 8, + /* MCI_GPM_COEX_BT_UPDATE_FLAGS */ + MCI_GPM_COEX_W_BT_FLAGS = 6, + MCI_GPM_COEX_B_BT_FLAGS_OP = 10 +}; + +enum mci_gpm_subtype { + MCI_GPM_BT_CAL_REQ = 0, + MCI_GPM_BT_CAL_GRANT = 1, + MCI_GPM_BT_CAL_DONE = 2, + MCI_GPM_WLAN_CAL_REQ = 3, + MCI_GPM_WLAN_CAL_GRANT = 4, + MCI_GPM_WLAN_CAL_DONE = 5, + MCI_GPM_COEX_AGENT = 0x0c, + MCI_GPM_RSVD_PATTERN = 0xfe, + MCI_GPM_RSVD_PATTERN32 = 0xfefefefe, + MCI_GPM_BT_DEBUG = 0xff +}; + +enum mci_bt_state { + MCI_BT_SLEEP, + MCI_BT_AWAKE, + MCI_BT_CAL_START, + MCI_BT_CAL +}; + +/* Type of state query */ +enum mci_state_type { + MCI_STATE_ENABLE, + MCI_STATE_INIT_GPM_OFFSET, + MCI_STATE_NEXT_GPM_OFFSET, + MCI_STATE_LAST_GPM_OFFSET, + MCI_STATE_BT, + MCI_STATE_SET_BT_SLEEP, + MCI_STATE_SET_BT_AWAKE, + MCI_STATE_SET_BT_CAL_START, + MCI_STATE_SET_BT_CAL, + MCI_STATE_LAST_SCHD_MSG_OFFSET, + MCI_STATE_REMOTE_SLEEP, + MCI_STATE_CONT_RSSI_POWER, + MCI_STATE_CONT_PRIORITY, + MCI_STATE_CONT_TXRX, + MCI_STATE_RESET_REQ_WAKE, + MCI_STATE_SEND_WLAN_COEX_VERSION, + MCI_STATE_SET_BT_COEX_VERSION, + MCI_STATE_SEND_WLAN_CHANNELS, + MCI_STATE_SEND_VERSION_QUERY, + MCI_STATE_SEND_STATUS_QUERY, + MCI_STATE_NEED_FLUSH_BT_INFO, + MCI_STATE_SET_CONCUR_TX_PRI, + MCI_STATE_RECOVER_RX, + MCI_STATE_NEED_FTP_STOMP, + MCI_STATE_NEED_TUNING, + MCI_STATE_DEBUG, + MCI_STATE_MAX +}; + +enum mci_gpm_coex_opcode { + MCI_GPM_COEX_VERSION_QUERY, + MCI_GPM_COEX_VERSION_RESPONSE, + MCI_GPM_COEX_STATUS_QUERY, + MCI_GPM_COEX_HALT_BT_GPM, + MCI_GPM_COEX_WLAN_CHANNELS, + MCI_GPM_COEX_BT_PROFILE_INFO, + MCI_GPM_COEX_BT_STATUS_UPDATE, + MCI_GPM_COEX_BT_UPDATE_FLAGS +}; + +#define MCI_GPM_NOMORE 0 +#define MCI_GPM_MORE 1 +#define MCI_GPM_INVALID 0xffffffff + +#define MCI_GPM_RECYCLE(_p_gpm) do { \ + *(((u32 *)_p_gpm) + MCI_GPM_COEX_W_GPM_PAYLOAD) = \ + MCI_GPM_RSVD_PATTERN32; \ +} while (0) + +#define MCI_GPM_TYPE(_p_gpm) \ + (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff) + +#define MCI_GPM_OPCODE(_p_gpm) \ + (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff) + +#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type) do { \ + *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff;\ +} while (0) + +#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) do { \ + *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff; \ + *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff;\ +} while (0) + +#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE) + +/* + * Functions that are available to the MCI driver core. + */ +bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, + u32 *payload, u8 len, bool wait_done, + bool check_bt); +u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); +void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, + u16 len, u32 sched_addr); +void ar9003_mci_cleanup(struct ath_hw *ah); +void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, + u32 *rx_msg_intr); + +/* + * These functions are used by ath9k_hw. + */ + +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT + +static inline bool ar9003_mci_is_ready(struct ath_hw *ah) +{ + return ah->btcoex_hw.mci.ready; +} +void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); +void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); +void ar9003_mci_init_cal_done(struct ath_hw *ah); +void ar9003_mci_set_full_sleep(struct ath_hw *ah); +void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); +void ar9003_mci_check_bt(struct ath_hw *ah); +bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); +int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata); +void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep); +void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); + +#else + +static inline bool ar9003_mci_is_ready(struct ath_hw *ah) +{ + return false; +} +static inline void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) +{ +} +static inline void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable) +{ +} +static inline void ar9003_mci_init_cal_done(struct ath_hw *ah) +{ +} +static inline void ar9003_mci_set_full_sleep(struct ath_hw *ah) +{ +} +static inline void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) +{ +} +static inline void ar9003_mci_check_bt(struct ath_hw *ah) +{ +} +static inline bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan) +{ + return false; +} +static inline int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata) +{ + return 0; +} +static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep) +{ +} +static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) +{ +} +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ + #endif diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2b0bfb8cca0..bc992b237ae 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -679,18 +679,17 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - if (AR_SREV_9330(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); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); if (AR_SREV_9462(ah)) ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); + if (chan->channel == 2484) + ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); + ah->modes_index = modesIndex; ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); @@ -1099,13 +1098,20 @@ 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; - 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_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; + + if (AR_SREV_9330(ah)) + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ; + + if (AR_SREV_9462(ah)) { + ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ; + ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9462_2GHZ; + ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ; + ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9462_5GHZ; + } } /* @@ -1313,13 +1319,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, * different modal values. */ if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); - - if (AR_SREV_9330(ah)) - REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); - if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) - REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); ah->modes_index = modesIndex; *ini_reloaded = true; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index ed64114571f..d834d97fe72 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -325,13 +325,18 @@ #define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200) -#define AR_PHY_CCA_NOM_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -110) -#define AR_PHY_CCA_NOM_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -115) -#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -125) -#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -125) +#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110 +#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115 +#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125 +#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125 #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_9462_2GHZ -127 +#define AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ -127 +#define AR_PHY_CCA_NOM_VAL_9462_5GHZ -127 +#define AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ -127 + #define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118 /* @@ -612,16 +617,14 @@ #define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4) #define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8) #define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc) -#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \ - 0x4c0 : 0x4c4)) -#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \ - 0x4c4 : 0x4c8)) +#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + 0x4c4)) +#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + 0x4c8)) #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) #define AR_PHY_65NM_CH0_SYNTH4 0x1608c -#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 -#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1 +#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) +#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) #define AR_PHY_65NM_CH0_SYNTH7 0x16098 #define AR_PHY_65NM_CH0_BIAS1 0x160c0 #define AR_PHY_65NM_CH0_BIAS2 0x160c4 diff --git a/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h deleted file mode 100644 index 5c55ae389ad..00000000000 --- a/drivers/net/wireless/ath/ath9k/ar9462_1p0_initvals.h +++ /dev/null @@ -1,1833 +0,0 @@ -/* - * Copyright (c) 2010 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef INITVALS_9462_1P0_H -#define INITVALS_9462_1P0_H - -/* AR9462 1.0 */ - -static const u32 ar9462_1p0_mac_core[][2] = { - /* Addr allmodes */ - {0x00000008, 0x00000000}, - {0x00000030, 0x00060085}, - {0x00000034, 0x00000005}, - {0x00000040, 0x00000000}, - {0x00000044, 0x00000000}, - {0x00000048, 0x00000008}, - {0x0000004c, 0x00000010}, - {0x00000050, 0x00000000}, - {0x00001040, 0x002ffc0f}, - {0x00001044, 0x002ffc0f}, - {0x00001048, 0x002ffc0f}, - {0x0000104c, 0x002ffc0f}, - {0x00001050, 0x002ffc0f}, - {0x00001054, 0x002ffc0f}, - {0x00001058, 0x002ffc0f}, - {0x0000105c, 0x002ffc0f}, - {0x00001060, 0x002ffc0f}, - {0x00001064, 0x002ffc0f}, - {0x000010f0, 0x00000100}, - {0x00001270, 0x00000000}, - {0x000012b0, 0x00000000}, - {0x000012f0, 0x00000000}, - {0x0000143c, 0x00000000}, - {0x0000147c, 0x00000000}, - {0x00001810, 0x0f000003}, - {0x00008000, 0x00000000}, - {0x00008004, 0x00000000}, - {0x00008008, 0x00000000}, - {0x0000800c, 0x00000000}, - {0x00008018, 0x00000000}, - {0x00008020, 0x00000000}, - {0x00008038, 0x00000000}, - {0x0000803c, 0x00080000}, - {0x00008040, 0x00000000}, - {0x00008044, 0x00000000}, - {0x00008048, 0x00000000}, - {0x0000804c, 0xffffffff}, - {0x00008050, 0xffffffff}, - {0x00008054, 0x00000000}, - {0x00008058, 0x00000000}, - {0x0000805c, 0x000fc78f}, - {0x00008060, 0x0000000f}, - {0x00008064, 0x00000000}, - {0x00008070, 0x00000310}, - {0x00008074, 0x00000020}, - {0x00008078, 0x00000000}, - {0x0000809c, 0x0000000f}, - {0x000080a0, 0x00000000}, - {0x000080a4, 0x02ff0000}, - {0x000080a8, 0x0e070605}, - {0x000080ac, 0x0000000d}, - {0x000080b0, 0x00000000}, - {0x000080b4, 0x00000000}, - {0x000080b8, 0x00000000}, - {0x000080bc, 0x00000000}, - {0x000080c0, 0x2a800000}, - {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c20}, - {0x000080cc, 0x01f40000}, - {0x000080d0, 0x00252500}, - {0x000080d4, 0x00a00005}, - {0x000080d8, 0x00400002}, - {0x000080dc, 0x00000000}, - {0x000080e0, 0xffffffff}, - {0x000080e4, 0x0000ffff}, - {0x000080e8, 0x3f3f3f3f}, - {0x000080ec, 0x00000000}, - {0x000080f0, 0x00000000}, - {0x000080f4, 0x00000000}, - {0x000080fc, 0x00020000}, - {0x00008100, 0x00000000}, - {0x00008108, 0x00000052}, - {0x0000810c, 0x00000000}, - {0x00008110, 0x00000000}, - {0x00008114, 0x000007ff}, - {0x00008118, 0x000000aa}, - {0x0000811c, 0x00003210}, - {0x00008124, 0x00000000}, - {0x00008128, 0x00000000}, - {0x0000812c, 0x00000000}, - {0x00008130, 0x00000000}, - {0x00008134, 0x00000000}, - {0x00008138, 0x00000000}, - {0x0000813c, 0x0000ffff}, - {0x00008144, 0xffffffff}, - {0x00008168, 0x00000000}, - {0x0000816c, 0x00000000}, - {0x00008170, 0x18486e00}, - {0x00008174, 0x33332210}, - {0x00008178, 0x00000000}, - {0x0000817c, 0x00020000}, - {0x000081c4, 0x33332210}, - {0x000081c8, 0x00000000}, - {0x000081cc, 0x00000000}, - {0x000081d4, 0x00000000}, - {0x000081ec, 0x00000000}, - {0x000081f0, 0x00000000}, - {0x000081f4, 0x00000000}, - {0x000081f8, 0x00000000}, - {0x000081fc, 0x00000000}, - {0x00008240, 0x00100000}, - {0x00008244, 0x0010f400}, - {0x00008248, 0x00000800}, - {0x0000824c, 0x0001e800}, - {0x00008250, 0x00000000}, - {0x00008254, 0x00000000}, - {0x00008258, 0x00000000}, - {0x0000825c, 0x40000000}, - {0x00008260, 0x00080922}, - {0x00008264, 0x99c00010}, - {0x00008268, 0xffffffff}, - {0x0000826c, 0x0000ffff}, - {0x00008270, 0x00000000}, - {0x00008274, 0x40000000}, - {0x00008278, 0x003e4180}, - {0x0000827c, 0x00000004}, - {0x00008284, 0x0000002c}, - {0x00008288, 0x0000002c}, - {0x0000828c, 0x000000ff}, - {0x00008294, 0x00000000}, - {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000140}, - {0x00008314, 0x00000000}, - {0x0000831c, 0x0000010d}, - {0x00008328, 0x00000000}, - {0x0000832c, 0x0000001f}, - {0x00008330, 0x00000302}, - {0x00008334, 0x00000700}, - {0x00008338, 0xffff0000}, - {0x0000833c, 0x02400000}, - {0x00008340, 0x000107ff}, - {0x00008344, 0xaa48105b}, - {0x00008348, 0x008f0000}, - {0x0000835c, 0x00000000}, - {0x00008360, 0xffffffff}, - {0x00008364, 0xffffffff}, - {0x00008368, 0x00000000}, - {0x00008370, 0x00000000}, - {0x00008374, 0x000000ff}, - {0x00008378, 0x00000000}, - {0x0000837c, 0x00000000}, - {0x00008380, 0xffffffff}, - {0x00008384, 0xffffffff}, - {0x00008390, 0xffffffff}, - {0x00008394, 0xffffffff}, - {0x00008398, 0x00000000}, - {0x0000839c, 0x00000000}, - {0x000083a4, 0x0000fa14}, - {0x000083a8, 0x000f0c00}, - {0x000083ac, 0x33332210}, - {0x000083b0, 0x33332210}, - {0x000083b4, 0x33332210}, - {0x000083b8, 0x33332210}, - {0x000083bc, 0x00000000}, - {0x000083c0, 0x00000000}, - {0x000083c4, 0x00000000}, - {0x000083c8, 0x00000000}, - {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, -}; - -static const u32 ar9462_1p0_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; - -static const u32 ar9462_1p0_sys3ant[][2] = { - /* Addr allmodes */ - {0x00063280, 0x00040807}, - {0x00063284, 0x104ccccc}, -}; - -static const u32 ar9462_pcie_phy_clkreq_enable_L1_1p0[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x10053e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000580c}, -}; - -static const u32 ar9462_1p0_mac_core_emulation[][2] = { - /* Addr allmodes */ - {0x00000030, 0x00060085}, - {0x00000044, 0x00000008}, - {0x0000805c, 0xffffc7ff}, - {0x00008344, 0xaa4a105b}, -}; - -static const u32 ar9462_common_rx_gain_table_ar9280_2p0_1p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - -static const u32 ar9200_ar9280_2p0_radio_core_1p0[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - -static const u32 ar9462_1p0_baseband_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221}, - {0x00009e44, 0x005c0000, 0x005c0000, 0x005c0000, 0x005c0000}, - {0x0000a258, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x0000a25c, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a28c, 0x00011111, 0x00011111, 0x00011111, 0x00011111}, - {0x0000a2c4, 0x00148d18, 0x00148d18, 0x00148d20, 0x00148d20}, - {0x0000a2d8, 0xf999a800, 0xf999a800, 0xf999a80c, 0xf999a80c}, - {0x0000a50c, 0x0000c00a, 0x0000c00a, 0x0000c00a, 0x0000c00a}, - {0x0000a538, 0x00038e8c, 0x00038e8c, 0x00038e8c, 0x00038e8c}, - {0x0000a53c, 0x0003cecc, 0x0003cecc, 0x0003cecc, 0x0003cecc}, - {0x0000a540, 0x00040ed4, 0x00040ed4, 0x00040ed4, 0x00040ed4}, - {0x0000a544, 0x00044edc, 0x00044edc, 0x00044edc, 0x00044edc}, - {0x0000a548, 0x00048ede, 0x00048ede, 0x00048ede, 0x00048ede}, - {0x0000a54c, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, - {0x0000a550, 0x00050f5e, 0x00050f5e, 0x00050f5e, 0x00050f5e}, - {0x0000a554, 0x00054f9e, 0x00054f9e, 0x00054f9e, 0x00054f9e}, - {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -}; - -static const u32 ar9462_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x10012e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000580c}, -}; - -static const u32 ar9462_common_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x01910190}, - {0x0000a030, 0x01930192}, - {0x0000a034, 0x01950194}, - {0x0000a038, 0x038a0196}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x22222229}, - {0x0000a084, 0x1d1d1d1d}, - {0x0000a088, 0x1d1d1d1d}, - {0x0000a08c, 0x1d1d1d1d}, - {0x0000a090, 0x171d1d1d}, - {0x0000a094, 0x11111717}, - {0x0000a098, 0x00030311}, - {0x0000a09c, 0x00000000}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x2a2d2f32}, - {0x0000b084, 0x21232328}, - {0x0000b088, 0x19191c1e}, - {0x0000b08c, 0x12141417}, - {0x0000b090, 0x07070e0e}, - {0x0000b094, 0x03030305}, - {0x0000b098, 0x00000003}, - {0x0000b09c, 0x00000000}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9462_modes_high_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, - {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, - {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, - {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, - {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, -}; - -static const u32 ar9462_common_wo_xlna_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x03820190}, - {0x0000a030, 0x03840383}, - {0x0000a034, 0x03880385}, - {0x0000a038, 0x038a0389}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x29292929}, - {0x0000a084, 0x29292929}, - {0x0000a088, 0x29292929}, - {0x0000a08c, 0x29292929}, - {0x0000a090, 0x22292929}, - {0x0000a094, 0x1d1d2222}, - {0x0000a098, 0x0c111117}, - {0x0000a09c, 0x00030303}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9462_1p0_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; - -static const u32 ar9462_1p0_mac_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8}, - {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017}, -}; - -static const u32 ar9462_1p0_tx_gain_table_baseband_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x00004002, 0x00004002, 0x00004002, 0x00004002}, - {0x0000a508, 0x00008004, 0x00008004, 0x00008004, 0x00008004}, - {0x0000a510, 0x0001000c, 0x0001000c, 0x0001000c, 0x0001000c}, - {0x0000a514, 0x0001420b, 0x0001420b, 0x0001420b, 0x0001420b}, - {0x0000a518, 0x0001824a, 0x0001824a, 0x0001824a, 0x0001824a}, - {0x0000a51c, 0x0001c44a, 0x0001c44a, 0x0001c44a, 0x0001c44a}, - {0x0000a520, 0x0002064a, 0x0002064a, 0x0002064a, 0x0002064a}, - {0x0000a524, 0x0002484a, 0x0002484a, 0x0002484a, 0x0002484a}, - {0x0000a528, 0x00028a4a, 0x00028a4a, 0x00028a4a, 0x00028a4a}, - {0x0000a52c, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, - {0x0000a530, 0x00030e4a, 0x00030e4a, 0x00030e4a, 0x00030e4a}, - {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a}, -}; - -static const u32 ar9462_1p0_radio_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, - {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24646c08, 0x24646c08}, - {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, - {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, - {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, - {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, - {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, -}; - -static const u32 ar9462_1p0_soc_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00001133, 0x00001133, 0x00001133, 0x00001133}, -}; - -static const u32 ar9462_1p0_baseband_core[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafe68e30}, - {0x00009804, 0xfd14e000}, - {0x00009808, 0x9c0a9f6b}, - {0x0000980c, 0x04900000}, - {0x00009814, 0x9280c00a}, - {0x00009818, 0x00000000}, - {0x0000981c, 0x00020028}, - {0x00009834, 0x6400a290}, - {0x00009838, 0x0108ecff}, - {0x0000983c, 0x0d000600}, - {0x00009880, 0x201fff00}, - {0x00009884, 0x00001042}, - {0x000098a4, 0x00200400}, - {0x000098b0, 0x32840bbe}, - {0x000098d0, 0x004b6a8e}, - {0x000098d4, 0x00000820}, - {0x000098dc, 0x00000000}, - {0x000098e4, 0x01ffffff}, - {0x000098e8, 0x01ffffff}, - {0x000098ec, 0x01ffffff}, - {0x000098f0, 0x00000000}, - {0x000098f4, 0x00000000}, - {0x00009c04, 0xff55ff55}, - {0x00009c08, 0x0320ff55}, - {0x00009c0c, 0x00000000}, - {0x00009c10, 0x00000000}, - {0x00009c14, 0x00046384}, - {0x00009c18, 0x05b6b440}, - {0x00009c1c, 0x00b6b440}, - {0x00009d00, 0xc080a333}, - {0x00009d04, 0x40206c10}, - {0x00009d08, 0x009c4060}, - {0x00009d0c, 0x9883800a}, - {0x00009d10, 0x01834061}, - {0x00009d14, 0x00c0040b}, - {0x00009d18, 0x00000000}, - {0x00009e08, 0x0038230c}, - {0x00009e24, 0x990bb514}, - {0x00009e28, 0x0c6f0000}, - {0x00009e30, 0x06336f77}, - {0x00009e34, 0x6af6532f}, - {0x00009e38, 0x0cc80c00}, - {0x00009e40, 0x0d261820}, - {0x00009e4c, 0x00001004}, - {0x00009e50, 0x00ff03f1}, - {0x00009e54, 0x64c355c7}, - {0x00009e58, 0xfd897735}, - {0x00009e5c, 0xe9198724}, - {0x00009fc0, 0x803e4788}, - {0x00009fc4, 0x0001efb5}, - {0x00009fcc, 0x40000014}, - {0x00009fd0, 0x01193b93}, - {0x0000a20c, 0x00000000}, - {0x0000a220, 0x00000000}, - {0x0000a224, 0x00000000}, - {0x0000a228, 0x10002310}, - {0x0000a23c, 0x00000000}, - {0x0000a244, 0x0c000000}, - {0x0000a2a0, 0x00000001}, - {0x0000a2c0, 0x00000001}, - {0x0000a2c8, 0x00000000}, - {0x0000a2cc, 0x18c43433}, - {0x0000a2d4, 0x00000000}, - {0x0000a2ec, 0x00000000}, - {0x0000a2f0, 0x00000000}, - {0x0000a2f4, 0x00000000}, - {0x0000a2f8, 0x00000000}, - {0x0000a344, 0x00000000}, - {0x0000a34c, 0x00000000}, - {0x0000a350, 0x0000a000}, - {0x0000a364, 0x00000000}, - {0x0000a370, 0x00000000}, - {0x0000a390, 0x00000001}, - {0x0000a394, 0x00000444}, - {0x0000a398, 0x001f0e0f}, - {0x0000a39c, 0x0075393f}, - {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x00000000}, - {0x0000a3a8, 0xaaaaaaaa}, - {0x0000a3ac, 0x3c466478}, - {0x0000a3c0, 0x20202020}, - {0x0000a3c4, 0x22222220}, - {0x0000a3c8, 0x20200020}, - {0x0000a3cc, 0x20202020}, - {0x0000a3d0, 0x20202020}, - {0x0000a3d4, 0x20202020}, - {0x0000a3d8, 0x20202020}, - {0x0000a3dc, 0x20202020}, - {0x0000a3e0, 0x20202020}, - {0x0000a3e4, 0x20202020}, - {0x0000a3e8, 0x20202020}, - {0x0000a3ec, 0x20202020}, - {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000006}, - {0x0000a3f8, 0x0c9bd380}, - {0x0000a3fc, 0x000f0f01}, - {0x0000a400, 0x8fa91f01}, - {0x0000a404, 0x00000000}, - {0x0000a408, 0x0e79e5c6}, - {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739ce}, - {0x0000a418, 0x2d001dce}, - {0x0000a41c, 0x1ce739ce}, - {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739ce}, - {0x0000a428, 0x000001ce}, - {0x0000a42c, 0x1ce739ce}, - {0x0000a430, 0x1ce739ce}, - {0x0000a434, 0x00000000}, - {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00100000}, - {0x0000a440, 0x00000000}, - {0x0000a444, 0x00000000}, - {0x0000a448, 0x05000080}, - {0x0000a44c, 0x00000001}, - {0x0000a450, 0x00010000}, - {0x0000a458, 0x00000000}, - {0x0000a644, 0xbfad9d74}, - {0x0000a648, 0x0048060a}, - {0x0000a64c, 0x00003c37}, - {0x0000a670, 0x03020100}, - {0x0000a674, 0x09080504}, - {0x0000a678, 0x0d0c0b0a}, - {0x0000a67c, 0x13121110}, - {0x0000a680, 0x31301514}, - {0x0000a684, 0x35343332}, - {0x0000a688, 0x00000036}, - {0x0000a690, 0x00000838}, - {0x0000a6b0, 0x0000000a}, - {0x0000a6b4, 0x28f12c01}, - {0x0000a7c0, 0x00000000}, - {0x0000a7c4, 0xfffffffc}, - {0x0000a7c8, 0x00000000}, - {0x0000a7cc, 0x00000000}, - {0x0000a7d0, 0x00000000}, - {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000001}, - {0x0000a8d0, 0x004b6a8e}, - {0x0000a8d4, 0x00000820}, - {0x0000a8dc, 0x00000000}, - {0x0000a8f0, 0x00000000}, - {0x0000a8f4, 0x00000000}, - {0x0000b2d0, 0x00000080}, - {0x0000b2d4, 0x00000000}, - {0x0000b2ec, 0x00000000}, - {0x0000b2f0, 0x00000000}, - {0x0000b2f4, 0x00000000}, - {0x0000b2f8, 0x00000000}, - {0x0000b408, 0x0e79e5c0}, - {0x0000b40c, 0x00820820}, - {0x0000b420, 0x00000000}, - {0x0000b6b0, 0x0000000a}, - {0x0000b6b4, 0x00c00001}, -}; - -static const u32 ar9462_1p0_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, - {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, - {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, - {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, - {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, - {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, - {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, - {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, - {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, - {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c782}, - {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, - {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, - {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x0131b7c0, 0x0131b7c4, 0x0131b7c4, 0x0131b7c0}, - {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, - {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, - {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, - {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, - {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, - {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, - {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, - {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, - {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, - {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, - {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, - {0x0000a288, 0x00000110, 0x00000110, 0x00100110, 0x00100110}, - {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, - {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, - {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, - {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, - {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, -}; - -static const u32 ar9462_modes_fast_clock_1p0[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00001030, 0x00000268, 0x000004d0}, - {0x00001070, 0x0000018c, 0x00000318}, - {0x000010b0, 0x00000fd0, 0x00001fa0}, - {0x00008014, 0x044c044c, 0x08980898}, - {0x0000801c, 0x148ec02b, 0x148ec057}, - {0x00008318, 0x000044c0, 0x00008980}, - {0x00009e00, 0x0372131c, 0x0372131c}, - {0x0000a230, 0x0000400b, 0x00004016}, - {0x0000a254, 0x00000898, 0x00001130}, -}; - -static const u32 ar9462_modes_low_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, - {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060}, - {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, - {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, -}; - -static const u32 ar9462_1p0_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, -}; - -static const u32 ar9462_common_mixed_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x03820190}, - {0x0000a030, 0x03840383}, - {0x0000a034, 0x03880385}, - {0x0000a038, 0x038a0389}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x29292929}, - {0x0000a084, 0x29292929}, - {0x0000a088, 0x29292929}, - {0x0000a08c, 0x29292929}, - {0x0000a090, 0x22292929}, - {0x0000a094, 0x1d1d2222}, - {0x0000a098, 0x0c111117}, - {0x0000a09c, 0x00030303}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x2a2d2f32}, - {0x0000b084, 0x21232328}, - {0x0000b088, 0x19191c1e}, - {0x0000b08c, 0x12141417}, - {0x0000b090, 0x07070e0e}, - {0x0000b094, 0x03030305}, - {0x0000b098, 0x00000003}, - {0x0000b09c, 0x00000000}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9462_pcie_phy_clkreq_disable_L1_1p0[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x10013e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000580c}, -}; - -static const u32 ar9462_1p0_baseband_core_emulation[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafa68e30}, - {0x00009884, 0x00002842}, - {0x00009c04, 0xff55ff55}, - {0x00009c08, 0x0320ff55}, - {0x00009e50, 0x00000000}, - {0x00009fcc, 0x00000014}, - {0x0000a344, 0x00000010}, - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x71733d01}, - {0x0000a3a0, 0xd0ad5c12}, - {0x0000a3c0, 0x22222220}, - {0x0000a3c4, 0x22222222}, - {0x0000a404, 0x00418a11}, - {0x0000a418, 0x050001ce}, - {0x0000a438, 0x00001800}, - {0x0000a458, 0x01444452}, - {0x0000a644, 0x3fad9d74}, - {0x0000a690, 0x00000038}, -}; - -static const u32 ar9462_1p0_radio_core[][2] = { - /* Addr allmodes */ - {0x00016000, 0x36db6db6}, - {0x00016004, 0x6db6db40}, - {0x00016008, 0x73f00000}, - {0x0001600c, 0x00000000}, - {0x00016010, 0x6d820001}, - {0x00016040, 0x7f80fff8}, - {0x0001604c, 0x2699e04f}, - {0x00016050, 0x6db6db6c}, - {0x00016054, 0x6db60000}, - {0x00016058, 0x6c200000}, - {0x00016080, 0x00040000}, - {0x00016084, 0x9a68048c}, - {0x00016088, 0x54214514}, - {0x0001608c, 0x12030409}, - {0x00016090, 0x24926490}, - {0x00016098, 0xd2888888}, - {0x000160a0, 0x0a108ffe}, - {0x000160a4, 0x812fc490}, - {0x000160a8, 0x423c8000}, - {0x000160b4, 0x92000000}, - {0x000160b8, 0x0285dddc}, - {0x000160bc, 0x02908888}, - {0x000160c0, 0x00adb6d0}, - {0x000160c4, 0x6db6db60}, - {0x000160c8, 0x6db6db6c}, - {0x000160cc, 0x0de6c1b0}, - {0x00016100, 0x3fffbe04}, - {0x00016104, 0xfff80000}, - {0x00016108, 0x00200400}, - {0x00016110, 0x00000000}, - {0x00016144, 0x02084080}, - {0x00016148, 0x000080c0}, - {0x00016280, 0x050a0001}, - {0x00016284, 0x3d841400}, - {0x00016288, 0x00000000}, - {0x0001628c, 0xe3000000}, - {0x00016290, 0xa1005080}, - {0x00016294, 0x00000020}, - {0x00016298, 0x50a02900}, - {0x00016340, 0x121e4276}, - {0x00016344, 0x00300000}, - {0x00016400, 0x36db6db6}, - {0x00016404, 0x6db6db40}, - {0x00016408, 0x73f00000}, - {0x0001640c, 0x00000000}, - {0x00016410, 0x6c800001}, - {0x00016440, 0x7f80fff8}, - {0x0001644c, 0x4699e04f}, - {0x00016450, 0x6db6db6c}, - {0x00016454, 0x6db60000}, - {0x00016500, 0x3fffbe04}, - {0x00016504, 0xfff80000}, - {0x00016508, 0x00200400}, - {0x00016510, 0x00000000}, - {0x00016544, 0x02084080}, - {0x00016548, 0x000080c0}, -}; - -static const u32 ar9462_1p0_soc_preamble[][2] = { - /* Addr allmodes */ - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, -}; - -static const u32 ar9462_1p0_sys2ant[][2] = { - /* Addr allmodes */ - {0x00063120, 0x00801980}, -}; - -#endif /* INITVALS_9462_1P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index dc2054f0378..b6ba1e8149b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -98,14 +98,6 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, }; -static const u32 ar9462_2p0_mac_core_emulation[][2] = { - /* Addr allmodes */ - {0x00000030, 0x000e0085}, - {0x00000044, 0x00000008}, - {0x0000805c, 0xffffc7ff}, - {0x00008344, 0xaa4a105b}, -}; - static const u32 ar9462_common_rx_gain_table_2p0[][2] = { /* Addr allmodes */ {0x0000a000, 0x00010000}, @@ -380,349 +372,6 @@ static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { {0x00018c08, 0x0003580c}, }; -static const u32 ar9462_2p0_sys3ant[][2] = { - /* Addr allmodes */ - {0x00063280, 0x00040807}, - {0x00063284, 0x104ccccc}, -}; - -static const u32 ar9462_common_rx_gain_table_ar9280_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - -static const u32 ar9200_ar9280_2p0_radio_core[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - -static const u32 ar9462_2p0_mac_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8}, - {0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017}, -}; - -static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, - {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, - {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, -}; - -static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221}, - {0x00009e44, 0xfc5c0000, 0xfc5c0000, 0xfc5c0000, 0xfc5c0000}, - {0x0000a258, 0x02020200, 0x02020200, 0x02020200, 0x02020200}, - {0x0000a25c, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a28c, 0x00011111, 0x00011111, 0x00011111, 0x00011111}, - {0x0000a2c4, 0x00148d18, 0x00148d18, 0x00148d20, 0x00148d20}, - {0x0000a2d8, 0xf999a800, 0xf999a800, 0xf999a80c, 0xf999a80c}, - {0x0000a50c, 0x0000c00a, 0x0000c00a, 0x0000c00a, 0x0000c00a}, - {0x0000a538, 0x00038e8c, 0x00038e8c, 0x00038e8c, 0x00038e8c}, - {0x0000a53c, 0x0003cecc, 0x0003cecc, 0x0003cecc, 0x0003cecc}, - {0x0000a540, 0x00040ed4, 0x00040ed4, 0x00040ed4, 0x00040ed4}, - {0x0000a544, 0x00044edc, 0x00044edc, 0x00044edc, 0x00044edc}, - {0x0000a548, 0x00048ede, 0x00048ede, 0x00048ede, 0x00048ede}, - {0x0000a54c, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e}, - {0x0000a550, 0x00050f5e, 0x00050f5e, 0x00050f5e, 0x00050f5e}, - {0x0000a554, 0x00054f9e, 0x00054f9e, 0x00054f9e, 0x00054f9e}, - {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -}; - static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, @@ -1356,24 +1005,6 @@ static const u32 ar9462_2p0_radio_core[][2] = { {0x00016548, 0x000080c0}, }; -static const u32 ar9462_2p0_tx_gain_table_baseband_postamble_emulation[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x00004002, 0x00004002, 0x00004002, 0x00004002}, - {0x0000a508, 0x00008004, 0x00008004, 0x00008004, 0x00008004}, - {0x0000a510, 0x0001000c, 0x0001000c, 0x0001000c, 0x0001000c}, - {0x0000a514, 0x0001420b, 0x0001420b, 0x0001420b, 0x0001420b}, - {0x0000a518, 0x0001824a, 0x0001824a, 0x0001824a, 0x0001824a}, - {0x0000a51c, 0x0001c44a, 0x0001c44a, 0x0001c44a, 0x0001c44a}, - {0x0000a520, 0x0002064a, 0x0002064a, 0x0002064a, 0x0002064a}, - {0x0000a524, 0x0002484a, 0x0002484a, 0x0002484a, 0x0002484a}, - {0x0000a528, 0x00028a4a, 0x00028a4a, 0x00028a4a, 0x00028a4a}, - {0x0000a52c, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a}, - {0x0000a530, 0x00030e4a, 0x00030e4a, 0x00030e4a, 0x00030e4a}, - {0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a}, -}; - static const u32 ar9462_2p0_soc_preamble[][2] = { /* Addr allmodes */ {0x00007020, 0x00000000}, @@ -1381,11 +1012,6 @@ static const u32 ar9462_2p0_soc_preamble[][2] = { {0x00007038, 0x000004c2}, }; -static const u32 ar9462_2p0_sys2ant[][2] = { - /* Addr allmodes */ - {0x00063120, 0x00801980}, -}; - static const u32 ar9462_2p0_mac_core[][2] = { /* Addr allmodes */ {0x00000008, 0x00000000}, @@ -1822,75 +1448,6 @@ static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = { {0x0000b1fc, 0x00000196}, }; -static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, - {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, - {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, - {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, - {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, - {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, - {0x00016054, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180}, - {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, - {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, - {0x00016454, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180}, -}; - static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = { /* Addr allmodes */ {0x000018c0, 0x10101010}, @@ -1903,26 +1460,4 @@ static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = { {0x000018dc, 0x10101010}, }; -static const u32 ar9462_2p0_baseband_core_emulation[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafa68e30}, - {0x00009884, 0x00002842}, - {0x00009c04, 0xff55ff55}, - {0x00009c08, 0x0320ff55}, - {0x00009e50, 0x00000000}, - {0x00009fcc, 0x00000014}, - {0x0000a344, 0x00000010}, - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x71733d01}, - {0x0000a3a0, 0xd0ad5c12}, - {0x0000a3c0, 0x22222220}, - {0x0000a3c4, 0x22222222}, - {0x0000a404, 0x00418a11}, - {0x0000a418, 0x050001ce}, - {0x0000a438, 0x00001800}, - {0x0000a458, 0x01444452}, - {0x0000a644, 0x3fad9d74}, - {0x0000a690, 0x00000038}, -}; - #endif /* INITVALS_9462_2P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 171ccf7c972..8c84049682a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -299,7 +299,6 @@ struct ath_tx { struct ath_rx_edma { struct sk_buff_head rx_fifo; - struct sk_buff_head rx_buffers; u32 rx_fifo_hwsize; }; @@ -454,9 +453,39 @@ struct ath_btcoex { struct ath_mci_profile mci; }; -int ath_init_btcoex_timer(struct ath_softc *sc); +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT +int ath9k_init_btcoex(struct ath_softc *sc); +void ath9k_deinit_btcoex(struct ath_softc *sc); +void ath9k_start_btcoex(struct ath_softc *sc); +void ath9k_stop_btcoex(struct ath_softc *sc); void ath9k_btcoex_timer_resume(struct ath_softc *sc); void ath9k_btcoex_timer_pause(struct ath_softc *sc); +void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); +u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); +#else +static inline int ath9k_init_btcoex(struct ath_softc *sc) +{ + return 0; +} +static inline void ath9k_deinit_btcoex(struct ath_softc *sc) +{ +} +static inline void ath9k_start_btcoex(struct ath_softc *sc) +{ +} +static inline void ath9k_stop_btcoex(struct ath_softc *sc) +{ +} +static inline void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, + u32 status) +{ +} +static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, + u32 max_4ms_framelen) +{ + return 0; +} +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ /********************/ /* LED Control */ @@ -554,19 +583,13 @@ struct ath_ant_comb { #define SC_OP_INVALID BIT(0) #define SC_OP_BEACONS BIT(1) -#define SC_OP_RXAGGR BIT(2) -#define SC_OP_TXAGGR BIT(3) -#define SC_OP_OFFCHANNEL BIT(4) -#define SC_OP_PREAMBLE_SHORT BIT(5) -#define SC_OP_PROTECT_ENABLE BIT(6) -#define SC_OP_RXFLUSH BIT(7) -#define SC_OP_LED_ASSOCIATED BIT(8) -#define SC_OP_LED_ON BIT(9) -#define SC_OP_TSF_RESET BIT(11) -#define SC_OP_BT_PRIORITY_DETECTED BIT(12) -#define SC_OP_BT_SCAN BIT(13) -#define SC_OP_ANI_RUN BIT(14) -#define SC_OP_PRIM_STA_VIF BIT(15) +#define SC_OP_OFFCHANNEL BIT(2) +#define SC_OP_RXFLUSH BIT(3) +#define SC_OP_TSF_RESET BIT(4) +#define SC_OP_BT_PRIORITY_DETECTED BIT(5) +#define SC_OP_BT_SCAN BIT(6) +#define SC_OP_ANI_RUN BIT(7) +#define SC_OP_PRIM_STA_VIF BIT(8) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) @@ -588,15 +611,12 @@ struct ath9k_vif_iter_data { int nstations; /* number of station vifs */ int nwds; /* number of WDS vifs */ int nadhocs; /* number of adhoc vifs */ - int nothers; /* number of vifs not specified above. */ }; struct ath_softc { struct ieee80211_hw *hw; struct device *dev; - int chan_idx; - int chan_is_ht; struct survey_info *cur_survey; struct survey_info survey[ATH9K_NUM_CHANNELS]; @@ -650,8 +670,11 @@ struct ath_softc { struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; struct delayed_work hw_pll_work; + +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex btcoex; struct ath_mci_coex mci_coex; +#endif struct ath_descdma txsdma; diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b8967e482e6..626418222c8 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -67,7 +67,7 @@ int ath_beaconq_config(struct ath_softc *sc) * up rate codes, and channel flags. Beacons are always sent out at the * lowest rate, and are not retried. */ -static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, +static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, struct ath_buf *bf, int rateidx) { struct sk_buff *skb = bf->bf_mpdu; @@ -82,7 +82,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, sband = &sc->sbands[common->hw->conf.channel->band]; rate = sband->bitrates[rateidx].hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + if (vif->bss_conf.use_short_preamble) rate |= sband->bitrates[rateidx].hw_value_short; memset(&info, 0, sizeof(info)); @@ -91,7 +91,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, info.txpower = MAX_RATE_POWER; info.keyix = ATH9K_TXKEYIX_INVALID; info.keytype = ATH9K_KEY_TYPE_CLEAR; - info.flags = ATH9K_TXDESC_NOACK; + info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_INTREQ; info.buf_addr[0] = bf->bf_buf_addr; info.buf_len[0] = roundup(skb->len, 4); @@ -209,7 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, } } - ath_beacon_setup(sc, avp, bf, info->control.rates[0].idx); + ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); while (skb) { ath_tx_cabq(hw, skb); @@ -355,7 +355,6 @@ void ath_beacon_tasklet(unsigned long data) struct ath_common *common = ath9k_hw_common(ah); struct ath_buf *bf = NULL; struct ieee80211_vif *vif; - struct ath_tx_status ts; bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); int slot; u32 bfaddr, bc = 0; @@ -462,11 +461,6 @@ void ath_beacon_tasklet(unsigned long data) ath9k_hw_txstart(ah, sc->beacon.beaconq); sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ - if (edma) { - spin_lock_bh(&sc->sc_pcu_lock); - ath9k_hw_txprocdesc(ah, bf->bf_desc, (void *)&ts); - spin_unlock_bh(&sc->sc_pcu_lock); - } } } diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index a6712a95d76..ec327199341 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -68,9 +68,6 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) u32 i, idx; bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - if (AR_SREV_9300_20_OR_LATER(ah)) rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; @@ -98,12 +95,43 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) } EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw); -void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah) +void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah) { + struct ath_common *common = ath9k_hw_common(ah); struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) + /* + * Check if BTCOEX is globally disabled. + */ + if (!common->btcoex_enabled) { + btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; return; + } + + if (AR_SREV_9462(ah)) { + btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI; + } else if (AR_SREV_9300_20_OR_LATER(ah)) { + btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; + btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; + btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; + btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300; + } else if (AR_SREV_9280_20_OR_LATER(ah)) { + btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280; + btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280; + + if (AR_SREV_9285(ah)) { + btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; + btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9285; + } else { + btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; + } + } +} +EXPORT_SYMBOL(ath9k_hw_btcoex_init_scheme); + +void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah) +{ + struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; /* connect bt_active to baseband */ REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL, @@ -127,9 +155,6 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - /* btcoex 3-wire */ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | @@ -152,13 +177,34 @@ void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire); +void ath9k_hw_btcoex_init_mci(struct ath_hw *ah) +{ + ah->btcoex_hw.mci.ready = false; + ah->btcoex_hw.mci.bt_state = 0; + ah->btcoex_hw.mci.bt_ver_major = 3; + ah->btcoex_hw.mci.bt_ver_minor = 0; + ah->btcoex_hw.mci.bt_version_known = false; + ah->btcoex_hw.mci.update_2g5g = true; + ah->btcoex_hw.mci.is_2g = true; + ah->btcoex_hw.mci.wlan_channels_update = false; + ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000; + ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff; + ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff; + ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff; + ah->btcoex_hw.mci.query_bt = true; + ah->btcoex_hw.mci.unhalt_bt_gpm = true; + ah->btcoex_hw.mci.halted_bt_gpm = false; + ah->btcoex_hw.mci.need_flush_btinfo = false; + ah->btcoex_hw.mci.wlan_cal_seq = 0; + ah->btcoex_hw.mci.wlan_cal_done = 0; + ah->btcoex_hw.mci.config = 0x2201; +} +EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci); + static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - /* Configure the desired GPIO port for TX_FRAME output */ ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); @@ -170,9 +216,6 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | SM(wlan_weight, AR_BTCOEX_WL_WGHT); } @@ -261,9 +304,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; int i; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - btcoex_hw->enabled = false; if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); @@ -312,9 +352,6 @@ static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type) { - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - if (AR_SREV_9300_20_OR_LATER(ah)) { ar9003_btcoex_bt_stomp(ah, stomp_type); return; diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 278361c867c..8f93aef4414 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h @@ -67,7 +67,6 @@ struct ath9k_hw_mci { u32 wlan_cal_done; u32 config; u8 *gpm_buf; - u8 *sched_buf; bool ready; bool update_2g5g; bool is_2g; @@ -98,13 +97,14 @@ struct ath_btcoex_hw { u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; }; +void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah); void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah); void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah); +void ath9k_hw_btcoex_init_mci(struct ath_hw *ah); void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, u32 bt_weight, u32 wlan_weight); -void ath9k_hw_btcoex_enable(struct ath_hw *ah); void ath9k_hw_btcoex_disable(struct ath_hw *ah); void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 68d972bf232..35d1c8e91d1 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -451,109 +451,6 @@ static const struct file_operations fops_interrupt = { .llseek = default_llseek, }; -static const char *channel_type_str(enum nl80211_channel_type t) -{ - switch (t) { - case NL80211_CHAN_NO_HT: - return "no ht"; - case NL80211_CHAN_HT20: - return "ht20"; - case NL80211_CHAN_HT40MINUS: - return "ht40-"; - case NL80211_CHAN_HT40PLUS: - return "ht40+"; - default: - return "???"; - } -} - -static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - struct ieee80211_channel *chan = sc->hw->conf.channel; - struct ieee80211_conf *conf = &(sc->hw->conf); - char buf[512]; - unsigned int len = 0; - u8 addr[ETH_ALEN]; - u32 tmp; - - len += snprintf(buf + len, sizeof(buf) - len, - "%s (chan=%d center-freq: %d MHz channel-type: %d (%s))\n", - wiphy_name(sc->hw->wiphy), - ieee80211_frequency_to_channel(chan->center_freq), - chan->center_freq, - conf->channel_type, - channel_type_str(conf->channel_type)); - - ath9k_ps_wakeup(sc); - put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); - put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); - len += snprintf(buf + len, sizeof(buf) - len, - "addr: %pM\n", addr); - put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_BSSMSKL), addr); - put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); - len += snprintf(buf + len, sizeof(buf) - len, - "addrmask: %pM\n", addr); - tmp = ath9k_hw_getrxfilter(sc->sc_ah); - ath9k_ps_restore(sc); - len += snprintf(buf + len, sizeof(buf) - len, - "rfilt: 0x%x", tmp); - if (tmp & ATH9K_RX_FILTER_UCAST) - len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); - if (tmp & ATH9K_RX_FILTER_MCAST) - len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); - if (tmp & ATH9K_RX_FILTER_BCAST) - len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); - if (tmp & ATH9K_RX_FILTER_CONTROL) - len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); - if (tmp & ATH9K_RX_FILTER_BEACON) - len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); - if (tmp & ATH9K_RX_FILTER_PROM) - len += snprintf(buf + len, sizeof(buf) - len, " PROM"); - if (tmp & ATH9K_RX_FILTER_PROBEREQ) - len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); - if (tmp & ATH9K_RX_FILTER_PHYERR) - len += snprintf(buf + len, sizeof(buf) - len, " PHYERR"); - if (tmp & ATH9K_RX_FILTER_MYBEACON) - len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON"); - if (tmp & ATH9K_RX_FILTER_COMP_BAR) - len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); - if (tmp & ATH9K_RX_FILTER_PSPOLL) - len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL"); - if (tmp & ATH9K_RX_FILTER_PHYRADAR) - len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); - if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) - len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); - - len += snprintf(buf + len, sizeof(buf) - len, - "\n\nReset causes:\n" - " baseband hang: %d\n" - " baseband watchdog: %d\n" - " fatal hardware error interrupt: %d\n" - " tx hardware error: %d\n" - " tx path hang: %d\n" - " pll rx hang: %d\n", - sc->debug.stats.reset[RESET_TYPE_BB_HANG], - sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG], - sc->debug.stats.reset[RESET_TYPE_FATAL_INT], - sc->debug.stats.reset[RESET_TYPE_TX_ERROR], - sc->debug.stats.reset[RESET_TYPE_TX_HANG], - sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_wiphy = { - .read = read_file_wiphy, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum #define PR(str, elem) \ do { \ @@ -763,87 +660,128 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, { struct ath_softc *sc = file->private_data; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_hw *ah = sc->sc_ah; struct ieee80211_hw *hw = sc->hw; - char *buf; - unsigned int len = 0, size = 8000; + struct ath9k_vif_iter_data iter_data; + char buf[512]; + unsigned int len = 0; ssize_t retval = 0; unsigned int reg; - struct ath9k_vif_iter_data iter_data; + u32 rxfilter; - ath9k_calculate_iter_data(hw, NULL, &iter_data); - - buf = kzalloc(size, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; + len += snprintf(buf + len, sizeof(buf) - len, + "BSSID: %pM\n", common->curbssid); + len += snprintf(buf + len, sizeof(buf) - len, + "BSSID-MASK: %pM\n", common->bssidmask); + len += snprintf(buf + len, sizeof(buf) - len, + "OPMODE: %s\n", ath_opmode_to_string(sc->sc_ah->opmode)); ath9k_ps_wakeup(sc); - len += snprintf(buf + len, size - len, - "curbssid: %pM\n" - "OP-Mode: %s(%i)\n" - "Beacon-Timer-Register: 0x%x\n", - common->curbssid, - ath_opmode_to_string(sc->sc_ah->opmode), - (int)(sc->sc_ah->opmode), - REG_READ(ah, AR_BEACON_PERIOD)); - - reg = REG_READ(ah, AR_TIMER_MODE); + rxfilter = ath9k_hw_getrxfilter(sc->sc_ah); ath9k_ps_restore(sc); - len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (", - reg); - if (reg & AR_TBTT_TIMER_EN) - len += snprintf(buf + len, size - len, "TBTT "); - if (reg & AR_DBA_TIMER_EN) - len += snprintf(buf + len, size - len, "DBA "); - if (reg & AR_SWBA_TIMER_EN) - len += snprintf(buf + len, size - len, "SWBA "); - if (reg & AR_HCF_TIMER_EN) - len += snprintf(buf + len, size - len, "HCF "); - if (reg & AR_TIM_TIMER_EN) - len += snprintf(buf + len, size - len, "TIM "); - if (reg & AR_DTIM_TIMER_EN) - len += snprintf(buf + len, size - len, "DTIM "); - len += snprintf(buf + len, size - len, ")\n"); + + len += snprintf(buf + len, sizeof(buf) - len, + "RXFILTER: 0x%x", rxfilter); + + if (rxfilter & ATH9K_RX_FILTER_UCAST) + len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); + if (rxfilter & ATH9K_RX_FILTER_MCAST) + len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); + if (rxfilter & ATH9K_RX_FILTER_BCAST) + len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); + if (rxfilter & ATH9K_RX_FILTER_CONTROL) + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); + if (rxfilter & ATH9K_RX_FILTER_BEACON) + len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); + if (rxfilter & ATH9K_RX_FILTER_PROM) + len += snprintf(buf + len, sizeof(buf) - len, " PROM"); + if (rxfilter & ATH9K_RX_FILTER_PROBEREQ) + len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); + if (rxfilter & ATH9K_RX_FILTER_PHYERR) + len += snprintf(buf + len, sizeof(buf) - len, " PHYERR"); + if (rxfilter & ATH9K_RX_FILTER_MYBEACON) + len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON"); + if (rxfilter & ATH9K_RX_FILTER_COMP_BAR) + len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); + if (rxfilter & ATH9K_RX_FILTER_PSPOLL) + len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL"); + if (rxfilter & ATH9K_RX_FILTER_PHYRADAR) + len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); + if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL) + len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); + if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER) + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER"); + + len += snprintf(buf + len, sizeof(buf) - len, "\n"); reg = sc->sc_ah->imask; - len += snprintf(buf + len, size - len, "imask: 0x%x (", reg); + + len += snprintf(buf + len, sizeof(buf) - len, "INTERRUPT-MASK: 0x%x", reg); + if (reg & ATH9K_INT_SWBA) - len += snprintf(buf + len, size - len, "SWBA "); + len += snprintf(buf + len, sizeof(buf) - len, " SWBA"); if (reg & ATH9K_INT_BMISS) - len += snprintf(buf + len, size - len, "BMISS "); + len += snprintf(buf + len, sizeof(buf) - len, " BMISS"); if (reg & ATH9K_INT_CST) - len += snprintf(buf + len, size - len, "CST "); + len += snprintf(buf + len, sizeof(buf) - len, " CST"); if (reg & ATH9K_INT_RX) - len += snprintf(buf + len, size - len, "RX "); + len += snprintf(buf + len, sizeof(buf) - len, " RX"); if (reg & ATH9K_INT_RXHP) - len += snprintf(buf + len, size - len, "RXHP "); + len += snprintf(buf + len, sizeof(buf) - len, " RXHP"); if (reg & ATH9K_INT_RXLP) - len += snprintf(buf + len, size - len, "RXLP "); + len += snprintf(buf + len, sizeof(buf) - len, " RXLP"); if (reg & ATH9K_INT_BB_WATCHDOG) - len += snprintf(buf + len, size - len, "BB_WATCHDOG "); - /* there are other IRQs if one wanted to add them. */ - len += snprintf(buf + len, size - len, ")\n"); + len += snprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG"); - len += snprintf(buf + len, size - len, - "VIF Counts: AP: %i STA: %i MESH: %i WDS: %i" - " ADHOC: %i OTHER: %i nvifs: %hi beacon-vifs: %hi\n", + len += snprintf(buf + len, sizeof(buf) - len, "\n"); + + ath9k_calculate_iter_data(hw, NULL, &iter_data); + + len += snprintf(buf + len, sizeof(buf) - len, + "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" + " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", iter_data.naps, iter_data.nstations, iter_data.nmeshes, - iter_data.nwds, iter_data.nadhocs, iter_data.nothers, + iter_data.nwds, iter_data.nadhocs, sc->nvifs, sc->nbcnvifs); - len += snprintf(buf + len, size - len, - "Calculated-BSSID-Mask: %pM\n", - iter_data.mask); - - if (len > size) - len = size; + if (len > sizeof(buf)) + len = sizeof(buf); retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return retval; } +static ssize_t read_file_reset(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_softc *sc = file->private_data; + char buf[512]; + unsigned int len = 0; + + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "Baseband Hang", + sc->debug.stats.reset[RESET_TYPE_BB_HANG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "Baseband Watchdog", + sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "Fatal HW Error", + sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "TX HW error", + sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "TX Path Hang", + sc->debug.stats.reset[RESET_TYPE_TX_HANG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "PLL RX Hang", + sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, struct ath_txq *txq, unsigned int flags) @@ -880,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) TX_STAT_INC(qnum, delim_underrun); +#ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock(&sc->debug.samp_lock); TX_SAMP_DBG(jiffies) = jiffies; TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0; @@ -906,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES; spin_unlock(&sc->debug.samp_lock); +#endif #undef TX_SAMP_DBG } @@ -931,16 +871,23 @@ static const struct file_operations fops_misc = { .llseek = default_llseek, }; +static const struct file_operations fops_reset = { + .read = read_file_reset, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { #define PHY_ERR(s, p) \ - len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \ + len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \ sc->debug.stats.rxstats.phy_err_stats[p]); struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 1400; + unsigned int len = 0, size = 1600; ssize_t retval = 0; buf = kzalloc(size, GFP_KERNEL); @@ -948,87 +895,59 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, return -ENOMEM; len += snprintf(buf + len, size - len, - "%18s : %10u\n", "CRC ERR", + "%22s : %10u\n", "CRC ERR", sc->debug.stats.rxstats.crc_err); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "DECRYPT CRC ERR", + "%22s : %10u\n", "DECRYPT CRC ERR", sc->debug.stats.rxstats.decrypt_crc_err); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "PHY ERR", + "%22s : %10u\n", "PHY ERR", sc->debug.stats.rxstats.phy_err); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "MIC ERR", + "%22s : %10u\n", "MIC ERR", sc->debug.stats.rxstats.mic_err); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "PRE-DELIM CRC ERR", + "%22s : %10u\n", "PRE-DELIM CRC ERR", sc->debug.stats.rxstats.pre_delim_crc_err); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "POST-DELIM CRC ERR", + "%22s : %10u\n", "POST-DELIM CRC ERR", sc->debug.stats.rxstats.post_delim_crc_err); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "DECRYPT BUSY ERR", + "%22s : %10u\n", "DECRYPT BUSY ERR", sc->debug.stats.rxstats.decrypt_busy_err); - len += snprintf(buf + len, size - len, - "%18s : %10d\n", "RSSI-CTL0", - sc->debug.stats.rxstats.rs_rssi_ctl0); - - len += snprintf(buf + len, size - len, - "%18s : %10d\n", "RSSI-CTL1", - sc->debug.stats.rxstats.rs_rssi_ctl1); - - len += snprintf(buf + len, size - len, - "%18s : %10d\n", "RSSI-CTL2", - sc->debug.stats.rxstats.rs_rssi_ctl2); - - len += snprintf(buf + len, size - len, - "%18s : %10d\n", "RSSI-EXT0", - sc->debug.stats.rxstats.rs_rssi_ext0); + PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN); + PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING); + PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY); + PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE); + PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH); + PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR); + PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE); + PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR); + PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING); + PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); + PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); + PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); + PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP); + PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE); + PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART); + PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT); + PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING); + PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC); + PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL); + PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE); + PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART); + PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); + PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP); + PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR); + PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); + PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL); len += snprintf(buf + len, size - len, - "%18s : %10d\n", "RSSI-EXT1", - sc->debug.stats.rxstats.rs_rssi_ext1); - - len += snprintf(buf + len, size - len, - "%18s : %10d\n", "RSSI-EXT2", - sc->debug.stats.rxstats.rs_rssi_ext2); - - len += snprintf(buf + len, size - len, - "%18s : %10d\n", "Rx Antenna", - sc->debug.stats.rxstats.rs_antenna); - - PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); - PHY_ERR("TIMING", ATH9K_PHYERR_TIMING); - PHY_ERR("PARITY", ATH9K_PHYERR_PARITY); - PHY_ERR("RATE", ATH9K_PHYERR_RATE); - PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH); - PHY_ERR("RADAR", ATH9K_PHYERR_RADAR); - PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE); - PHY_ERR("TOR", ATH9K_PHYERR_TOR); - PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING); - PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY); - PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL); - PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL); - PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP); - PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE); - PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART); - PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT); - PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING); - PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC); - PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL); - PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE); - PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART); - PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL); - PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP); - PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR); - PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); - PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); - - len += snprintf(buf + len, size - len, - "%18s : %10u\n", "RX-Pkts-All", + "%22s : %10u\n", "RX-Pkts-All", sc->debug.stats.rxstats.rx_pkts_all); len += snprintf(buf + len, size - len, - "%18s : %10u\n", "RX-Bytes-All", + "%22s : %10u\n", "RX-Bytes-All", sc->debug.stats.rxstats.rx_bytes_all); if (len > size) @@ -1049,8 +968,6 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) #define RX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].rs\ [sc->debug.rsidx].c) - u32 phyerr; - RX_STAT_INC(rx_pkts_all); sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; @@ -1069,20 +986,11 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) if (rs->rs_status & ATH9K_RXERR_PHY) { RX_STAT_INC(phy_err); - phyerr = rs->rs_phyerr & 0x24; - RX_PHY_ERR_INC(phyerr); + if (rs->rs_phyerr < ATH9K_PHYERR_MAX) + RX_PHY_ERR_INC(rs->rs_phyerr); } - sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0; - sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1; - sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2; - - sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0; - sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1; - sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2; - - sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna; - +#ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock(&sc->debug.samp_lock); RX_SAMP_DBG(jiffies) = jiffies; RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0; @@ -1099,6 +1007,8 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES; spin_unlock(&sc->debug.samp_lock); +#endif + #undef RX_STAT_INC #undef RX_PHY_ERR_INC #undef RX_SAMP_DBG @@ -1342,6 +1252,8 @@ static const struct file_operations fops_modal_eeprom = { .llseek = default_llseek, }; +#ifdef CONFIG_ATH9K_MAC_DEBUG + void ath9k_debug_samp_bb_mac(struct ath_softc *sc) { #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c) @@ -1615,6 +1527,7 @@ static const struct file_operations fops_samps = { .llseek = default_llseek, }; +#endif int ath9k_init_debug(struct ath_hw *ah) { @@ -1637,14 +1550,14 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_dma); debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_interrupt); - debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - sc, &fops_wiphy); debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_xmit); debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_stations); debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_misc); + debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_reset); debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_recv); debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, @@ -1668,8 +1581,10 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_base_eeprom); debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_modal_eeprom); +#ifdef CONFIG_ATH9K_MAC_DEBUG debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_samps); +#endif debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); @@ -1677,10 +1592,5 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); - sc->debug.regidx = 0; - memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp)); - sc->debug.sampidx = 0; - sc->debug.tsidx = 0; - sc->debug.rsidx = 0; return 0; } diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 776a24ada60..64fcfad467b 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -165,13 +165,6 @@ struct ath_rx_stats { u32 post_delim_crc_err; u32 decrypt_busy_err; u32 phy_err_stats[ATH9K_PHYERR_MAX]; - int8_t rs_rssi_ctl0; - int8_t rs_rssi_ctl1; - int8_t rs_rssi_ctl2; - int8_t rs_rssi_ext0; - int8_t rs_rssi_ext1; - int8_t rs_rssi_ext2; - u8 rs_antenna; }; enum ath_reset_type { @@ -235,16 +228,17 @@ struct ath9k_debug { struct dentry *debugfs_phy; u32 regidx; struct ath_stats stats; +#ifdef CONFIG_ATH9K_MAC_DEBUG spinlock_t samp_lock; struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES]; u8 sampidx; u8 tsidx; u8 rsidx; +#endif }; int ath9k_init_debug(struct ath_hw *ah); -void ath9k_debug_samp_bb_mac(struct ath_softc *sc); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, struct ath_txq *txq, @@ -258,10 +252,6 @@ static inline int ath9k_init_debug(struct ath_hw *ah) return 0; } -static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) -{ -} - static inline void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) { @@ -282,4 +272,17 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc, #endif /* CONFIG_ATH9K_DEBUGFS */ +#ifdef CONFIG_ATH9K_MAC_DEBUG + +void ath9k_debug_samp_bb_mac(struct ath_softc *sc); + +#else + +static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc) +{ +} + +#endif + + #endif /* DEBUG_H */ diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 597c84e31ad..fbe23de1297 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -110,6 +110,8 @@ void ath_start_rfkill_poll(struct ath_softc *sc) wiphy_rfkill_start_polling(sc->hw->wiphy); } +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT + /******************/ /* BTCOEX */ /******************/ @@ -245,13 +247,10 @@ static void ath_btcoex_no_stomp_timer(void *arg) ath9k_ps_restore(sc); } -int ath_init_btcoex_timer(struct ath_softc *sc) +static int ath_init_btcoex_timer(struct ath_softc *sc) { struct ath_btcoex *btcoex = &sc->btcoex; - if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_NONE) - return 0; - btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * btcoex->btcoex_period / 100; @@ -284,9 +283,6 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - /* make sure duty cycle timer is also stopped when resuming */ if (btcoex->hw_timer_enabled) ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); @@ -307,9 +303,6 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) struct ath_btcoex *btcoex = &sc->btcoex; struct ath_hw *ah = sc->sc_ah; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - del_timer_sync(&btcoex->period_timer); if (btcoex->hw_timer_enabled) @@ -317,3 +310,114 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) btcoex->hw_timer_enabled = false; } + +u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) +{ + struct ath_mci_profile *mci = &sc->btcoex.mci; + u16 aggr_limit = 0; + + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) + aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; + else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) + aggr_limit = min((max_4ms_framelen * 3) / 8, + (u32)ATH_AMPDU_LIMIT_MAX); + + return aggr_limit; +} + +void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status) +{ + struct ath_hw *ah = sc->sc_ah; + + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) + if (status & ATH9K_INT_GENTIMER) + ath_gen_timer_isr(sc->sc_ah); + + if (status & ATH9K_INT_MCI) + ath_mci_intr(sc); +} + +void ath9k_start_btcoex(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && + !ah->btcoex_hw.enabled) { + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + ath9k_hw_btcoex_enable(ah); + + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) + ath9k_btcoex_timer_resume(sc); + } +} + +void ath9k_stop_btcoex(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + if (ah->btcoex_hw.enabled && + ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { + ath9k_hw_btcoex_disable(ah); + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) + ath9k_btcoex_timer_pause(sc); + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) + ath_mci_flush_profile(&sc->btcoex.mci); + } +} + +void ath9k_deinit_btcoex(struct ath_softc *sc) +{ + if ((sc->btcoex.no_stomp_timer) && + ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) + ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); + + if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI) + ath_mci_cleanup(sc); +} + +int ath9k_init_btcoex(struct ath_softc *sc) +{ + struct ath_txq *txq; + struct ath_hw *ah = sc->sc_ah; + int r; + + ath9k_hw_btcoex_init_scheme(ah); + + switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) { + case ATH_BTCOEX_CFG_NONE: + break; + case ATH_BTCOEX_CFG_2WIRE: + ath9k_hw_btcoex_init_2wire(sc->sc_ah); + break; + case ATH_BTCOEX_CFG_3WIRE: + ath9k_hw_btcoex_init_3wire(sc->sc_ah); + r = ath_init_btcoex_timer(sc); + if (r) + return -1; + txq = sc->tx.txq_map[WME_AC_BE]; + ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); + sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + break; + case ATH_BTCOEX_CFG_MCI: + sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; + INIT_LIST_HEAD(&sc->btcoex.mci.info); + + r = ath_mci_setup(sc); + if (r) + return r; + + ath9k_hw_btcoex_init_mci(ah); + + break; + default: + WARN_ON(1); + break; + } + + return 0; +} + +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 77c8ded8de5..424aabb2c73 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } -static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, - u32 drv_info) +static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) { int transfer, err; const void *data = hif_dev->firmware->data; @@ -982,7 +981,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, return -ENOMEM; while (len) { - transfer = min_t(int, len, 4096); + transfer = min_t(size_t, len, 4096); memcpy(buf, data, transfer); err = usb_control_msg(hif_dev->udev, @@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, } kfree(buf); - if (IS_AR7010_DEVICE(drv_info)) + if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) firm_offset = AR7010_FIRMWARE_TEXT; else firm_offset = AR9271_FIRMWARE_TEXT; @@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, return 0; } -static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) +static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { - int ret, idx; struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; struct usb_endpoint_descriptor *endp; + int ret, idx; - /* Request firmware */ - ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, - &hif_dev->udev->dev); - if (ret) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name); - goto err_fw_req; - } - - /* Download firmware */ - ret = ath9k_hif_usb_download_fw(hif_dev, drv_info); + ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s download failed\n", hif_dev->fw_name); - goto err_fw_download; + return ret; } /* On downloading the firmware to the target, the USB descriptor of EP4 @@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Unable to allocate URBs\n"); - goto err_fw_download; + return ret; } return 0; - -err_fw_download: - release_firmware(hif_dev->firmware); -err_fw_req: - hif_dev->firmware = NULL; - return ret; } static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) { ath9k_hif_usb_dealloc_urbs(hif_dev); - if (hif_dev->firmware) - release_firmware(hif_dev->firmware); +} + +/* + * If initialization fails or the FW cannot be retrieved, + * detach the device. + */ +static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) +{ + struct device *parent = hif_dev->udev->dev.parent; + + complete(&hif_dev->fw_done); + + if (parent) + device_lock(parent); + + device_release_driver(&hif_dev->udev->dev); + + if (parent) + device_unlock(parent); +} + +static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) +{ + struct hif_device_usb *hif_dev = context; + int ret; + + if (!fw) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Failed to get firmware %s\n", + hif_dev->fw_name); + goto err_fw; + } + + hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, + &hif_dev->udev->dev); + if (hif_dev->htc_handle == NULL) { + goto err_fw; + } + + hif_dev->firmware = fw; + + /* Proceed with initialization */ + + ret = ath9k_hif_usb_dev_init(hif_dev); + if (ret) + goto err_dev_init; + + ret = ath9k_htc_hw_init(hif_dev->htc_handle, + &hif_dev->interface->dev, + hif_dev->usb_device_id->idProduct, + hif_dev->udev->product, + hif_dev->usb_device_id->driver_info); + if (ret) { + ret = -EINVAL; + goto err_htc_hw_init; + } + + complete(&hif_dev->fw_done); + + return; + +err_htc_hw_init: + ath9k_hif_usb_dev_deinit(hif_dev); +err_dev_init: + ath9k_htc_hw_free(hif_dev->htc_handle); + release_firmware(fw); + hif_dev->firmware = NULL; +err_fw: + ath9k_hif_usb_firmware_fail(hif_dev); } /* @@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } usb_get_dev(udev); + hif_dev->udev = udev; hif_dev->interface = interface; - hif_dev->device_id = id->idProduct; + hif_dev->usb_device_id = id; #ifdef CONFIG_PM udev->reset_resume = 1; #endif usb_set_intfdata(interface, hif_dev); - hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, - &hif_dev->udev->dev); - if (hif_dev->htc_handle == NULL) { - ret = -ENOMEM; - goto err_htc_hw_alloc; - } + init_completion(&hif_dev->fw_done); /* Find out which firmware to load */ @@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, else hif_dev->fw_name = FIRMWARE_AR9271; - ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info); - if (ret) { - ret = -EINVAL; - goto err_hif_init_usb; - } - - ret = ath9k_htc_hw_init(hif_dev->htc_handle, - &interface->dev, hif_dev->device_id, - hif_dev->udev->product, id->driver_info); + ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, + &hif_dev->udev->dev, GFP_KERNEL, + hif_dev, ath9k_hif_usb_firmware_cb); if (ret) { - ret = -EINVAL; - goto err_htc_hw_init; + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Async request for firmware %s failed\n", + hif_dev->fw_name); + goto err_fw_req; } - dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n"); + dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", + hif_dev->fw_name); return 0; -err_htc_hw_init: - ath9k_hif_usb_dev_deinit(hif_dev); -err_hif_init_usb: - ath9k_htc_hw_free(hif_dev->htc_handle); -err_htc_hw_alloc: +err_fw_req: usb_set_intfdata(interface, NULL); kfree(hif_dev); usb_put_dev(udev); @@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (!hif_dev) return; - ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); - ath9k_hif_usb_dev_deinit(hif_dev); + wait_for_completion(&hif_dev->fw_done); + + if (hif_dev->firmware) { + ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); + ath9k_htc_hw_free(hif_dev->htc_handle); + ath9k_hif_usb_dev_deinit(hif_dev); + release_firmware(hif_dev->firmware); + } + usb_set_intfdata(interface, NULL); if (!unplugged && (hif_dev->flags & HIF_USB_START)) @@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) return ret; if (hif_dev->firmware) { - ret = ath9k_hif_usb_download_fw(hif_dev, - htc_handle->drv_priv->ah->hw_version.usbdev); + ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) goto fail_resume; } else { diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 794f63094e5..487ff658b4c 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -87,10 +87,11 @@ struct cmd_buf { #define HIF_USB_START BIT(0) struct hif_device_usb { - u16 device_id; struct usb_device *udev; struct usb_interface *interface; + const struct usb_device_id *usb_device_id; const struct firmware *firmware; + struct completion fw_done; struct htc_target *htc_handle; struct hif_usb_tx tx; struct usb_anchor regout_submitted; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index da5596766d8..135795257d9 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -400,9 +400,21 @@ struct ath_btcoex { u32 btscan_no_stomp; }; -void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv); -void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv); -void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT +void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product); +void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv); +void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv); +#else +static inline void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product) +{ +} +static inline void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv) +{ +} +static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv) +{ +} +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #define OP_INVALID BIT(0) #define OP_SCANNING BIT(1) @@ -483,7 +495,10 @@ struct ath9k_htc_priv { int cabq; int hwq_map[WME_NUM_AC]; +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex btcoex; +#endif + struct delayed_work coex_period_work; struct delayed_work duty_cycle_work; #ifdef CONFIG_ATH9K_HTC_DEBUGFS diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 6506e1fd503..1c10e2e5c23 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -20,6 +20,10 @@ /* BTCOEX */ /******************/ +#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193" + +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT + /* * Detects if there is any priority bt traffic */ @@ -111,13 +115,10 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) ath9k_hw_btcoex_enable(priv->ah); } -void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) +static void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) { struct ath_btcoex *btcoex = &priv->btcoex; - if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE) - return; - btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * btcoex->btcoex_period / 100; @@ -131,14 +132,11 @@ void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) * (Re)start btcoex work */ -void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) +static void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) { struct ath_btcoex *btcoex = &priv->btcoex; struct ath_hw *ah = priv->ah; - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE) - return; - ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex work\n"); btcoex->bt_priority_cnt = 0; @@ -151,15 +149,66 @@ void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) /* * Cancel btcoex and bt duty cycle work. */ -void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) +static void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) { - if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE) - return; - cancel_delayed_work_sync(&priv->coex_period_work); cancel_delayed_work_sync(&priv->duty_cycle_work); } +void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv) +{ + struct ath_hw *ah = priv->ah; + + if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + ath9k_hw_btcoex_enable(ah); + ath_htc_resume_btcoex_work(priv); + } +} + +void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv) +{ + struct ath_hw *ah = priv->ah; + + if (ah->btcoex_hw.enabled && + ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { + ath9k_hw_btcoex_disable(ah); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) + ath_htc_cancel_btcoex_work(priv); + } +} + +void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product) +{ + struct ath_hw *ah = priv->ah; + int qnum; + + if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { + ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; + } + + switch (ath9k_hw_get_btcoex_scheme(priv->ah)) { + case ATH_BTCOEX_CFG_NONE: + break; + case ATH_BTCOEX_CFG_3WIRE: + priv->ah->btcoex_hw.btactive_gpio = 7; + priv->ah->btcoex_hw.btpriority_gpio = 6; + priv->ah->btcoex_hw.wlanactive_gpio = 8; + priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + ath9k_hw_btcoex_init_3wire(priv->ah); + ath_htc_init_btcoex_work(priv); + qnum = priv->hwq_map[WME_AC_BE]; + ath9k_hw_init_btcoex_hw(priv->ah, qnum); + break; + default: + WARN_ON(1); + break; + } +} + +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ + /*******/ /* LED */ /*******/ diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9be10a2da1c..de5ee15ee63 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -41,8 +41,6 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); .max_power = 20, \ } -#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193" - static struct ieee80211_channel ath9k_2ghz_channels[] = { CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2417, 1), /* Channel 2 */ @@ -603,29 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) priv->ah->opmode = NL80211_IFTYPE_STATION; } -static void ath9k_init_btcoex(struct ath9k_htc_priv *priv) -{ - int qnum; - - switch (ath9k_hw_get_btcoex_scheme(priv->ah)) { - case ATH_BTCOEX_CFG_NONE: - break; - case ATH_BTCOEX_CFG_3WIRE: - priv->ah->btcoex_hw.btactive_gpio = 7; - priv->ah->btcoex_hw.btpriority_gpio = 6; - priv->ah->btcoex_hw.wlanactive_gpio = 8; - priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - ath9k_hw_btcoex_init_3wire(priv->ah); - ath_htc_init_btcoex_work(priv); - qnum = priv->hwq_map[WME_AC_BE]; - ath9k_hw_init_btcoex_hw(priv->ah, qnum); - break; - default: - WARN_ON(1); - break; - } -} - static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid, char *product, u32 drv_info) @@ -698,12 +673,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ath9k_cmn_init_crypto(ah); ath9k_init_channels_rates(priv); ath9k_init_misc(priv); - - if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { - ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; - if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) - ath9k_init_btcoex(priv); - } + ath9k_htc_init_btcoex(priv, product); return 0; @@ -741,6 +711,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + hw->queues = 4; hw->channel_change_time = 5000; hw->max_listen_interval = 10; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ef4c6066129..2b8f61c210e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -919,7 +919,6 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) /* setup initial channel */ init_channel = ath9k_cmn_get_curchannel(hw, ah); - ath9k_hw_htc_resetinit(ah); ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (ret) { ath_err(common, @@ -957,12 +956,8 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) mod_timer(&priv->tx.cleanup_timer, jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL)); - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); - ath9k_hw_btcoex_enable(ah); - ath_htc_resume_btcoex_work(priv); - } + ath9k_htc_start_btcoex(priv); + mutex_unlock(&priv->mutex); return ret; @@ -1009,12 +1004,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); - if (ah->btcoex_hw.enabled && - ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { - ath9k_hw_btcoex_disable(ah); - if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) - ath_htc_cancel_btcoex_work(priv); - } + ath9k_htc_stop_btcoex(priv); /* Remove a monitor interface if it's present. */ if (priv->ah->is_monitoring) @@ -1409,6 +1399,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, if (htc_modparam_nohwcrypt) return -ENOSPC; + if ((vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* + * For now, disable hw crypto for the RSN IBSS group keys. This + * could be optimized in the future to use a modified key cache + * design to support per-STA RX GTK, but until that gets + * implemented, use of software crypto for group addressed + * frames is a acceptable to allow RSN IBSS to be used. + */ + return -EOPNOTSUPP; + } + mutex_lock(&priv->mutex); ath_dbg(common, CONFIG, "Set HW Key\n"); ath9k_htc_ps_wakeup(priv); diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 1b90ed8795c..c25226a32dd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -431,11 +431,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct htc_target *target; target = kzalloc(sizeof(struct htc_target), GFP_KERNEL); - if (!target) { - printk(KERN_ERR "Unable to allocate memory for" - "target device\n"); + if (!target) return NULL; - } init_completion(&target->target_wait); init_completion(&target->cmd_wait); diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index c4ad0b06bdb..265bf77598a 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -24,7 +24,7 @@ static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah, bool power_off) { - if (ah->aspm_enabled != true) + if (!ah->aspm_enabled) return; ath9k_hw_ops(ah)->config_pci_powersave(ah, power_off); diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 87db1ee1c29..6c69e4e8b1c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -23,6 +23,7 @@ #include "hw-ops.h" #include "rc.h" #include "ar9003_mac.h" +#include "ar9003_mci.h" static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); @@ -448,6 +449,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ah->slottime = ATH9K_SLOT_TIME_9; ah->globaltxtimeout = (u32) -1; ah->power_mode = ATH9K_PM_UNDEFINED; + ah->htc_reset_init = true; } static int ath9k_hw_init_macaddr(struct ath_hw *ah) @@ -554,7 +556,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) return -EIO; } - if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { @@ -618,9 +620,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (!ah->is_pciexpress) ath9k_hw_disablepcie(ah); - if (!AR_SREV_9300_20_OR_LATER(ah)) - ar9002_hw_cck_chan14_spread(ah); - r = ath9k_hw_post_init(ah); if (r) return r; @@ -1385,10 +1384,16 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) static bool ath9k_hw_chip_reset(struct ath_hw *ah, struct ath9k_channel *chan) { - if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) { - if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) - return false; - } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) + int reset_type = ATH9K_RESET_WARM; + + if (AR_SREV_9280(ah)) { + if (ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) + reset_type = ATH9K_RESET_POWER_ON; + else + reset_type = ATH9K_RESET_COLD; + } + + if (!ath9k_hw_set_reset_reg(ah, reset_type)) return false; if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) @@ -1514,70 +1519,95 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_check_alive); -int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool bChannelChange) +/* + * Fast channel change: + * (Change synthesizer based on channel freq without resetting chip) + * + * Don't do FCC when + * - Flag is not set + * - Chip is just coming out of full sleep + * - Channel to be set is same as current channel + * - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel) + */ +static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; - u32 saveLedState; - struct ath9k_channel *curchan = ah->curchan; - u32 saveDefAntenna; - u32 macStaId1; - u64 tsf = 0; - int i, r; - bool allow_fbs = false; - bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); - bool save_fullsleep = ah->chip_fullsleep; + int ret; - if (mci) { + if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) + goto fail; - ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan)); + if (ah->chip_fullsleep) + goto fail; - if (mci_hw->bt_state == MCI_BT_CAL_START) { - u32 payload[4] = {0, 0, 0, 0}; + if (!ah->curchan) + goto fail; - ath_dbg(common, MCI, "MCI stop rx for BT CAL\n"); + if (chan->channel == ah->curchan->channel) + goto fail; - mci_hw->bt_state = MCI_BT_CAL; + if ((chan->channelFlags & CHANNEL_ALL) != + (ah->curchan->channelFlags & CHANNEL_ALL)) + goto fail; - /* - * MCI FIX: disable mci interrupt here. This is to avoid - * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and - * lead to mci_intr reentry. - */ + if (!ath9k_hw_check_alive(ah)) + goto fail; - ar9003_mci_disable_interrupt(ah); + /* + * For AR9462, make sure that calibration data for + * re-using are present. + */ + if (AR_SREV_9462(ah) && (!ah->caldata || + !ah->caldata->done_txiqcal_once || + !ah->caldata->done_txclcal_once || + !ah->caldata->rtt_hist.num_readings)) + goto fail; - ath_dbg(common, MCI, "send WLAN_CAL_GRANT\n"); - MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT); - ar9003_mci_send_message(ah, MCI_GPM, 0, payload, - 16, true, false); + ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", + ah->curchan->channel, chan->channel); - ath_dbg(common, MCI, "\nMCI BT is calibrating\n"); + ret = ath9k_hw_channel_change(ah, chan); + if (!ret) + goto fail; - /* Wait BT calibration to be completed for 25ms */ + ath9k_hw_loadnf(ah, ah->curchan); + ath9k_hw_start_nfcal(ah, true); - if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, - 0, 25000)) - ath_dbg(common, MCI, - "MCI got BT_CAL_DONE\n"); - else - ath_dbg(common, MCI, - "MCI ### BT cal takes to long, force bt_state to be bt_awake\n"); - mci_hw->bt_state = MCI_BT_AWAKE; - /* MCI FIX: enable mci interrupt here */ - ar9003_mci_enable_interrupt(ah); + if ((ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && ar9003_mci_is_ready(ah)) + ar9003_mci_2g5g_switch(ah, true); - return true; - } - } + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); + + return 0; +fail: + return -EINVAL; +} + +int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, + struct ath9k_hw_cal_data *caldata, bool fastcc) +{ + struct ath_common *common = ath9k_hw_common(ah); + u32 saveLedState; + u32 saveDefAntenna; + u32 macStaId1; + u64 tsf = 0; + int i, r; + bool start_mci_reset = false; + bool mci = !!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI); + bool save_fullsleep = ah->chip_fullsleep; + if (mci) { + start_mci_reset = ar9003_mci_start_reset(ah, chan); + if (start_mci_reset) + return 0; + } if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; - if (curchan && !ah->chip_fullsleep) - ath9k_hw_getnf(ah, curchan); + if (ah->curchan && !ah->chip_fullsleep) + ath9k_hw_getnf(ah, ah->curchan); ah->caldata = caldata; if (caldata && @@ -1590,47 +1620,14 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } ah->noise = ath9k_hw_getchan_noise(ah, chan); - if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) - bChannelChange = false; - - if (caldata && - caldata->done_txiqcal_once && - caldata->done_txclcal_once && - caldata->rtt_hist.num_readings) - allow_fbs = true; - - if (bChannelChange && - (ah->chip_fullsleep != true) && - (ah->curchan != NULL) && - (chan->channel != ah->curchan->channel) && - (allow_fbs || - ((chan->channelFlags & CHANNEL_ALL) == - (ah->curchan->channelFlags & CHANNEL_ALL)))) { - if (ath9k_hw_channel_change(ah, chan)) { - ath9k_hw_loadnf(ah, ah->curchan); - ath9k_hw_start_nfcal(ah, true); - if (mci && mci_hw->ready) - ar9003_mci_2g5g_switch(ah, true); - - if (AR_SREV_9271(ah)) - ar9002_hw_load_ani_reg(ah, chan); - return 0; - } - } - - if (mci) { - ar9003_mci_disable_interrupt(ah); - - if (mci_hw->ready && !save_fullsleep) { - ar9003_mci_mute_bt(ah); - udelay(20); - REG_WRITE(ah, AR_BTCOEX_CTRL, 0); - } - - mci_hw->bt_state = MCI_BT_SLEEP; - mci_hw->ready = false; + if (fastcc) { + r = ath9k_hw_do_fastcc(ah, chan); + if (!r) + return r; } + if (mci) + ar9003_mci_stop_bt(ah, save_fullsleep); saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA); if (saveDefAntenna == 0) @@ -1807,53 +1804,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_loadnf(ah, chan); ath9k_hw_start_nfcal(ah, true); - if (mci && mci_hw->ready) { - - if (IS_CHAN_2GHZ(chan) && - (mci_hw->bt_state == MCI_BT_SLEEP)) { - - if (ar9003_mci_check_int(ah, - AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) || - ar9003_mci_check_int(ah, - AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)) { - - /* - * BT is sleeping. Check if BT wakes up during - * WLAN calibration. If BT wakes up during - * WLAN calibration, need to go through all - * message exchanges again and recal. - */ - - ath_dbg(common, MCI, - "MCI BT wakes up during WLAN calibration\n"); - - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | - AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE); - ath_dbg(common, MCI, "MCI send REMOTE_RESET\n"); - ar9003_mci_remote_reset(ah, true); - ar9003_mci_send_sys_waking(ah, true); - udelay(1); - if (IS_CHAN_2GHZ(chan)) - ar9003_mci_send_lna_transfer(ah, true); - - mci_hw->bt_state = MCI_BT_AWAKE; - - ath_dbg(common, MCI, "MCI re-cal\n"); - - if (caldata) { - caldata->done_txiqcal_once = false; - caldata->done_txclcal_once = false; - caldata->rtt_hist.num_readings = 0; - } - - if (!ath9k_hw_init_cal(ah, chan)) - return -EIO; - - } - } - ar9003_mci_enable_interrupt(ah); - } + if (mci && ar9003_mci_end_reset(ah, chan, caldata)) + return -EIO; ENABLE_REGWRITE_BUFFER(ah); @@ -1894,24 +1846,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, #endif } - if (ah->btcoex_hw.enabled && - ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) + if (ath9k_hw_btcoex_is_enabled(ah)) ath9k_hw_btcoex_enable(ah); - if (mci && mci_hw->ready) { - /* - * check BT state again to make - * sure it's not changed. - */ - - ar9003_mci_sync_bt_state(ah); - ar9003_mci_2g5g_switch(ah, true); - - if ((mci_hw->bt_state == MCI_BT_AWAKE) && - (mci_hw->query_bt == true)) { - mci_hw->need_flush_btinfo = true; - } - } + if (mci) + ar9003_mci_check_bt(ah); if (AR_SREV_9300_20_OR_LATER(ah)) { ar9003_hw_bb_watchdog_config(ah); @@ -1962,8 +1901,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); /* Shutdown chip. Active low */ - if (!AR_SREV_5416(ah) && - !AR_SREV_9271(ah) && !AR_SREV_9462_10(ah)) { + if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) { REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); udelay(2); } @@ -2038,8 +1976,7 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) if (setChip) { if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { - if (ath9k_hw_set_reset_reg(ah, - ATH9K_RESET_POWER_ON) != true) { + if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { return false; } if (!AR_SREV_9300_20_OR_LATER(ah)) @@ -2077,7 +2014,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) { struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; int status = true, setChip = true; static const char *modes[] = { "AWAKE", @@ -2101,20 +2037,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) break; case ATH9K_PM_FULL_SLEEP: - - if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) { - if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && - (mci->bt_state != MCI_BT_SLEEP) && - !mci->halted_bt_gpm) { - ath_dbg(common, MCI, - "MCI halt BT GPM (full_sleep)\n"); - ar9003_mci_send_coex_halt_bt_gpm(ah, - true, true); - } - - mci->ready = false; - REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2); - } + if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) + ar9003_mci_set_full_sleep(ah); ath9k_set_power_sleep(ah, setChip); ah->chip_fullsleep = true; @@ -2304,7 +2228,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_common *common = ath9k_hw_common(ah); - struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; unsigned int chip_chainmask; u16 eeval; @@ -2423,30 +2346,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; - if (common->btcoex_enabled) { - if (AR_SREV_9462(ah)) - btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI; - else if (AR_SREV_9300_20_OR_LATER(ah)) { - btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; - btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; - btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; - btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300; - } else if (AR_SREV_9280_20_OR_LATER(ah)) { - btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280; - btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280; - - if (AR_SREV_9285(ah)) { - btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; - btcoex_hw->btpriority_gpio = - ATH_BTPRIORITY_GPIO_9285; - } else { - btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; - } - } - } else { - btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; - } - if (AR_SREV_9300_20_OR_LATER(ah)) { pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah)) @@ -2530,8 +2429,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9485_OR_LATER(ah)) ah->enabled_cals |= TX_IQ_ON_AGC_CAL; } - if (AR_SREV_9462(ah)) - pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; + + if (AR_SREV_9462(ah)) { + + if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) + pCap->hw_caps |= ATH9K_HW_CAP_MCI; + + if (AR_SREV_9462_20(ah)) + pCap->hw_caps |= ATH9K_HW_CAP_RTT; + + } + return 0; } @@ -2657,12 +2565,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) } EXPORT_SYMBOL(ath9k_hw_set_gpio); -u32 ath9k_hw_getdefantenna(struct ath_hw *ah) -{ - return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; -} -EXPORT_SYMBOL(ath9k_hw_getdefantenna); - void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna) { REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); @@ -2720,6 +2622,7 @@ bool ath9k_hw_phy_disable(struct ath_hw *ah) return false; ath9k_hw_init_pll(ah, NULL); + ah->htc_reset_init = true; return true; } EXPORT_SYMBOL(ath9k_hw_phy_disable); @@ -3080,12 +2983,6 @@ EXPORT_SYMBOL(ath_gen_timer_isr); /* HTC */ /********/ -void ath9k_hw_htc_resetinit(struct ath_hw *ah) -{ - ah->htc_reset_init = true; -} -EXPORT_SYMBOL(ath9k_hw_htc_resetinit); - static struct { u32 version; const char * name; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index c8261d4fc78..aa1680a0c7f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -209,11 +209,7 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_5GHZ = BIT(12), ATH9K_HW_CAP_APM = BIT(13), ATH9K_HW_CAP_RTT = BIT(14), -#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT ATH9K_HW_CAP_MCI = BIT(15), -#else - ATH9K_HW_CAP_MCI = 0, -#endif ATH9K_HW_CAP_DFS = BIT(16), }; @@ -432,161 +428,6 @@ enum ath9k_rx_qtype { ATH9K_RX_QUEUE_MAX, }; -enum mci_message_header { /* length of payload */ - MCI_LNA_CTRL = 0x10, /* len = 0 */ - MCI_CONT_NACK = 0x20, /* len = 0 */ - MCI_CONT_INFO = 0x30, /* len = 4 */ - MCI_CONT_RST = 0x40, /* len = 0 */ - MCI_SCHD_INFO = 0x50, /* len = 16 */ - MCI_CPU_INT = 0x60, /* len = 4 */ - MCI_SYS_WAKING = 0x70, /* len = 0 */ - MCI_GPM = 0x80, /* len = 16 */ - MCI_LNA_INFO = 0x90, /* len = 1 */ - MCI_LNA_STATE = 0x94, - MCI_LNA_TAKE = 0x98, - MCI_LNA_TRANS = 0x9c, - MCI_SYS_SLEEPING = 0xa0, /* len = 0 */ - MCI_REQ_WAKE = 0xc0, /* len = 0 */ - MCI_DEBUG_16 = 0xfe, /* len = 2 */ - MCI_REMOTE_RESET = 0xff /* len = 16 */ -}; - -enum ath_mci_gpm_coex_profile_type { - MCI_GPM_COEX_PROFILE_UNKNOWN, - MCI_GPM_COEX_PROFILE_RFCOMM, - MCI_GPM_COEX_PROFILE_A2DP, - MCI_GPM_COEX_PROFILE_HID, - MCI_GPM_COEX_PROFILE_BNEP, - MCI_GPM_COEX_PROFILE_VOICE, - MCI_GPM_COEX_PROFILE_MAX -}; - -/* MCI GPM/Coex opcode/type definitions */ -enum { - MCI_GPM_COEX_W_GPM_PAYLOAD = 1, - MCI_GPM_COEX_B_GPM_TYPE = 4, - MCI_GPM_COEX_B_GPM_OPCODE = 5, - /* MCI_GPM_WLAN_CAL_REQ, MCI_GPM_WLAN_CAL_DONE */ - MCI_GPM_WLAN_CAL_W_SEQUENCE = 2, - - /* MCI_GPM_COEX_VERSION_QUERY */ - /* MCI_GPM_COEX_VERSION_RESPONSE */ - MCI_GPM_COEX_B_MAJOR_VERSION = 6, - MCI_GPM_COEX_B_MINOR_VERSION = 7, - /* MCI_GPM_COEX_STATUS_QUERY */ - MCI_GPM_COEX_B_BT_BITMAP = 6, - MCI_GPM_COEX_B_WLAN_BITMAP = 7, - /* MCI_GPM_COEX_HALT_BT_GPM */ - MCI_GPM_COEX_B_HALT_STATE = 6, - /* MCI_GPM_COEX_WLAN_CHANNELS */ - MCI_GPM_COEX_B_CHANNEL_MAP = 6, - /* MCI_GPM_COEX_BT_PROFILE_INFO */ - MCI_GPM_COEX_B_PROFILE_TYPE = 6, - MCI_GPM_COEX_B_PROFILE_LINKID = 7, - MCI_GPM_COEX_B_PROFILE_STATE = 8, - MCI_GPM_COEX_B_PROFILE_ROLE = 9, - MCI_GPM_COEX_B_PROFILE_RATE = 10, - MCI_GPM_COEX_B_PROFILE_VOTYPE = 11, - MCI_GPM_COEX_H_PROFILE_T = 12, - MCI_GPM_COEX_B_PROFILE_W = 14, - MCI_GPM_COEX_B_PROFILE_A = 15, - /* MCI_GPM_COEX_BT_STATUS_UPDATE */ - MCI_GPM_COEX_B_STATUS_TYPE = 6, - MCI_GPM_COEX_B_STATUS_LINKID = 7, - MCI_GPM_COEX_B_STATUS_STATE = 8, - /* MCI_GPM_COEX_BT_UPDATE_FLAGS */ - MCI_GPM_COEX_W_BT_FLAGS = 6, - MCI_GPM_COEX_B_BT_FLAGS_OP = 10 -}; - -enum mci_gpm_subtype { - MCI_GPM_BT_CAL_REQ = 0, - MCI_GPM_BT_CAL_GRANT = 1, - MCI_GPM_BT_CAL_DONE = 2, - MCI_GPM_WLAN_CAL_REQ = 3, - MCI_GPM_WLAN_CAL_GRANT = 4, - MCI_GPM_WLAN_CAL_DONE = 5, - MCI_GPM_COEX_AGENT = 0x0c, - MCI_GPM_RSVD_PATTERN = 0xfe, - MCI_GPM_RSVD_PATTERN32 = 0xfefefefe, - MCI_GPM_BT_DEBUG = 0xff -}; - -enum mci_bt_state { - MCI_BT_SLEEP, - MCI_BT_AWAKE, - MCI_BT_CAL_START, - MCI_BT_CAL -}; - -/* Type of state query */ -enum mci_state_type { - MCI_STATE_ENABLE, - MCI_STATE_INIT_GPM_OFFSET, - MCI_STATE_NEXT_GPM_OFFSET, - MCI_STATE_LAST_GPM_OFFSET, - MCI_STATE_BT, - MCI_STATE_SET_BT_SLEEP, - MCI_STATE_SET_BT_AWAKE, - MCI_STATE_SET_BT_CAL_START, - MCI_STATE_SET_BT_CAL, - MCI_STATE_LAST_SCHD_MSG_OFFSET, - MCI_STATE_REMOTE_SLEEP, - MCI_STATE_CONT_RSSI_POWER, - MCI_STATE_CONT_PRIORITY, - MCI_STATE_CONT_TXRX, - MCI_STATE_RESET_REQ_WAKE, - MCI_STATE_SEND_WLAN_COEX_VERSION, - MCI_STATE_SET_BT_COEX_VERSION, - MCI_STATE_SEND_WLAN_CHANNELS, - MCI_STATE_SEND_VERSION_QUERY, - MCI_STATE_SEND_STATUS_QUERY, - MCI_STATE_NEED_FLUSH_BT_INFO, - MCI_STATE_SET_CONCUR_TX_PRI, - MCI_STATE_RECOVER_RX, - MCI_STATE_NEED_FTP_STOMP, - MCI_STATE_NEED_TUNING, - MCI_STATE_DEBUG, - MCI_STATE_MAX -}; - -enum mci_gpm_coex_opcode { - MCI_GPM_COEX_VERSION_QUERY, - MCI_GPM_COEX_VERSION_RESPONSE, - MCI_GPM_COEX_STATUS_QUERY, - MCI_GPM_COEX_HALT_BT_GPM, - MCI_GPM_COEX_WLAN_CHANNELS, - MCI_GPM_COEX_BT_PROFILE_INFO, - MCI_GPM_COEX_BT_STATUS_UPDATE, - MCI_GPM_COEX_BT_UPDATE_FLAGS -}; - -#define MCI_GPM_NOMORE 0 -#define MCI_GPM_MORE 1 -#define MCI_GPM_INVALID 0xffffffff - -#define MCI_GPM_RECYCLE(_p_gpm) do { \ - *(((u32 *)_p_gpm) + MCI_GPM_COEX_W_GPM_PAYLOAD) = \ - MCI_GPM_RSVD_PATTERN32; \ -} while (0) - -#define MCI_GPM_TYPE(_p_gpm) \ - (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) & 0xff) - -#define MCI_GPM_OPCODE(_p_gpm) \ - (*(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) & 0xff) - -#define MCI_GPM_SET_CAL_TYPE(_p_gpm, _cal_type) do { \ - *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_cal_type) & 0xff;\ -} while (0) - -#define MCI_GPM_SET_TYPE_OPCODE(_p_gpm, _type, _opcode) do { \ - *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_TYPE) = (_type) & 0xff; \ - *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_GPM_OPCODE) = (_opcode) & 0xff;\ -} while (0) - -#define MCI_GPM_IS_CAL_TYPE(_type) ((_type) <= MCI_GPM_WLAN_CAL_DONE) - struct ath9k_beacon_state { u32 bs_nexttbtt; u32 bs_nextdtim; @@ -956,8 +797,9 @@ struct ath_hw { int firpwr[5]; enum ath9k_ani_cmd ani_function; - /* Bluetooth coexistance */ +#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex_hw btcoex_hw; +#endif u32 intr_txqs; u8 txchainmask; @@ -985,19 +827,14 @@ struct ath_hw { struct ar5416IniArray iniAddac; struct ar5416IniArray iniPcieSerdes; struct ar5416IniArray iniPcieSerdesLowPower; - struct ar5416IniArray iniModesAdditional; - struct ar5416IniArray iniModesAdditional_40M; + struct ar5416IniArray iniModesFastClock; + struct ar5416IniArray iniAdditional; struct ar5416IniArray iniModesRxGain; struct ar5416IniArray iniModesTxGain; - struct ar5416IniArray iniModes_9271_1_0_only; struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; struct ar5416IniArray ini_japan2484; - struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271; - struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271; struct ar5416IniArray iniModes_9271_ANI_reg; - struct ar5416IniArray iniModes_high_power_tx_gain_9271; - struct ar5416IniArray iniModes_normal_power_tx_gain_9271; struct ar5416IniArray ini_radio_post_sys2ant; struct ar5416IniArray ini_BTCOEX_MAX_TXPWR; @@ -1082,7 +919,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid); void ath9k_hw_deinit(struct ath_hw *ah); int ath9k_hw_init(struct ath_hw *ah); int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, - struct ath9k_hw_cal_data *caldata, bool bChannelChange); + struct ath9k_hw_cal_data *caldata, bool fastcc); int ath9k_hw_fill_cap_info(struct ath_hw *ah); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); @@ -1092,7 +929,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, u32 ah_signal_type); void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); -u32 ath9k_hw_getdefantenna(struct ath_hw *ah); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); /* General Operation */ @@ -1146,9 +982,6 @@ void ath_gen_timer_isr(struct ath_hw *hw); void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); -/* HTC */ -void ath9k_hw_htc_resetinit(struct ath_hw *ah); - /* PHY */ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, u32 *coef_mantissa, u32 *coef_exponent); @@ -1158,7 +991,6 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); * Code Specific to AR5008, AR9001 or AR9002, * we stuff these here to avoid callbacks for AR9003. */ -void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); int ar9002_hw_rf_claim(struct ath_hw *ah); void ar9002_hw_enable_async_fifo(struct ath_hw *ah); @@ -1205,41 +1037,31 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); -bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, - u32 *payload, u8 len, bool wait_done, - bool check_bt); -void ar9003_mci_mute_bt(struct ath_hw *ah); -u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); -void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, - u16 len, u32 sched_addr); -void ar9003_mci_cleanup(struct ath_hw *ah); -void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt, - bool wait_done); -u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, - u8 gpm_opcode, int time_out); -void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g); -void ar9003_mci_disable_interrupt(struct ath_hw *ah); -void ar9003_mci_enable_interrupt(struct ath_hw *ah); -void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); -void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, - bool is_full_sleep); -bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints); -void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done); -void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done); -void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done); -void ar9003_mci_sync_bt_state(struct ath_hw *ah); -void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, - u32 *rx_msg_intr); - #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT +static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) +{ + return ah->btcoex_hw.enabled; +} +void ath9k_hw_btcoex_enable(struct ath_hw *ah); static inline enum ath_btcoex_scheme ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) { return ah->btcoex_hw.scheme; } #else -#define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE -#endif +static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) +{ + return false; +} +static inline void ath9k_hw_btcoex_enable(struct ath_hw *ah) +{ +} +static inline enum ath_btcoex_scheme +ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) +{ + return ATH_BTCOEX_CFG_NONE; +} +#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #define ATH9K_CLOCK_RATE_CCK 22 #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 53a005d288a..60159f4ee53 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -172,7 +172,7 @@ static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) struct ath_common *common = ath9k_hw_common(ah); struct ath_softc *sc = (struct ath_softc *) common->priv; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { unsigned long flags; spin_lock_irqsave(&sc->sc_serial_rw, flags); iowrite32(val, sc->mem + reg_offset); @@ -188,7 +188,7 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) struct ath_softc *sc = (struct ath_softc *) common->priv; u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { unsigned long flags; spin_lock_irqsave(&sc->sc_serial_rw, flags); val = ioread32(sc->mem + reg_offset); @@ -219,7 +219,7 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl unsigned long uninitialized_var(flags); u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) { + if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { spin_lock_irqsave(&sc->sc_serial_rw, flags); val = __ath9k_reg_rmw(sc, reg_offset, set, clr); spin_unlock_irqrestore(&sc->sc_serial_rw, flags); @@ -419,66 +419,6 @@ fail: return error; } -static int ath9k_init_btcoex(struct ath_softc *sc) -{ - struct ath_txq *txq; - struct ath_hw *ah = sc->sc_ah; - int r; - - switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) { - case ATH_BTCOEX_CFG_NONE: - break; - case ATH_BTCOEX_CFG_2WIRE: - ath9k_hw_btcoex_init_2wire(sc->sc_ah); - break; - case ATH_BTCOEX_CFG_3WIRE: - ath9k_hw_btcoex_init_3wire(sc->sc_ah); - r = ath_init_btcoex_timer(sc); - if (r) - return -1; - txq = sc->tx.txq_map[WME_AC_BE]; - ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); - sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - break; - case ATH_BTCOEX_CFG_MCI: - sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; - INIT_LIST_HEAD(&sc->btcoex.mci.info); - - r = ath_mci_setup(sc); - if (r) - return r; - - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) { - ah->btcoex_hw.mci.ready = false; - ah->btcoex_hw.mci.bt_state = 0; - ah->btcoex_hw.mci.bt_ver_major = 3; - ah->btcoex_hw.mci.bt_ver_minor = 0; - ah->btcoex_hw.mci.bt_version_known = false; - ah->btcoex_hw.mci.update_2g5g = true; - ah->btcoex_hw.mci.is_2g = true; - ah->btcoex_hw.mci.wlan_channels_update = false; - ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000; - ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff; - ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff; - ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff; - ah->btcoex_hw.mci.query_bt = true; - ah->btcoex_hw.mci.unhalt_bt_gpm = true; - ah->btcoex_hw.mci.halted_bt_gpm = false; - ah->btcoex_hw.mci.need_flush_btinfo = false; - ah->btcoex_hw.mci.wlan_cal_seq = 0; - ah->btcoex_hw.mci.wlan_cal_done = 0; - ah->btcoex_hw.mci.config = 0x2201; - } - break; - default: - WARN_ON(1); - break; - } - - return 0; -} - static int ath9k_init_queues(struct ath_softc *sc) { int i = 0; @@ -544,19 +484,11 @@ static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; + setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; - - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - sc->sc_flags |= SC_OP_TXAGGR; - sc->sc_flags |= SC_OP_RXAGGR; - } - - sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); - sc->beacon.slottime = ATH9K_SLOT_TIME_9; for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) @@ -615,9 +547,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, mutex_init(&sc->mutex); #ifdef CONFIG_ATH9K_DEBUGFS spin_lock_init(&sc->nodes_lock); - spin_lock_init(&sc->debug.samp_lock); INIT_LIST_HEAD(&sc->nodes); #endif +#ifdef CONFIG_ATH9K_MAC_DEBUG + spin_lock_init(&sc->debug.samp_lock); +#endif tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, (unsigned long)sc); @@ -880,12 +814,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc) if (sc->sbands[IEEE80211_BAND_5GHZ].channels) kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); - if ((sc->btcoex.no_stomp_timer) && - ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) - ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); - - if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI) - ath_mci_cleanup(sc); + ath9k_deinit_btcoex(sc); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e196aba77ac..f7bd2532269 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -185,13 +185,6 @@ bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q) } EXPORT_SYMBOL(ath9k_hw_stop_dma_queue); -void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) -{ - *txqs &= ah->intr_txqs; - ah->intr_txqs &= ~(*txqs); -} -EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs); - bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo) { @@ -340,6 +333,15 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, } EXPORT_SYMBOL(ath9k_hw_setuptxqueue); +static void ath9k_hw_clear_queue_interrupts(struct ath_hw *ah, u32 q) +{ + ah->txok_interrupt_mask &= ~(1 << q); + ah->txerr_interrupt_mask &= ~(1 << q); + ah->txdesc_interrupt_mask &= ~(1 << q); + ah->txeol_interrupt_mask &= ~(1 << q); + ah->txurn_interrupt_mask &= ~(1 << q); +} + bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) { struct ath_common *common = ath9k_hw_common(ah); @@ -354,11 +356,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) ath_dbg(common, QUEUE, "Release TX queue: %u\n", q); qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; - ah->txok_interrupt_mask &= ~(1 << q); - ah->txerr_interrupt_mask &= ~(1 << q); - ah->txdesc_interrupt_mask &= ~(1 << q); - ah->txeol_interrupt_mask &= ~(1 << q); - ah->txurn_interrupt_mask &= ~(1 << q); + ath9k_hw_clear_queue_interrupts(ah, q); ath9k_hw_set_txq_interrupts(ah, qi); return true; @@ -510,26 +508,17 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) if (AR_SREV_9300_20_OR_LATER(ah)) REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); - if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) + ath9k_hw_clear_queue_interrupts(ah, q); + if (qi->tqi_qflags & TXQ_FLAG_TXINT_ENABLE) { ah->txok_interrupt_mask |= 1 << q; - else - ah->txok_interrupt_mask &= ~(1 << q); - if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) ah->txerr_interrupt_mask |= 1 << q; - else - ah->txerr_interrupt_mask &= ~(1 << q); + } if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) ah->txdesc_interrupt_mask |= 1 << q; - else - ah->txdesc_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) ah->txeol_interrupt_mask |= 1 << q; - else - ah->txeol_interrupt_mask &= ~(1 << q); if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) ah->txurn_interrupt_mask |= 1 << q; - else - ah->txurn_interrupt_mask &= ~(1 << q); ath9k_hw_set_txq_interrupts(ah, qi); return true; @@ -745,7 +734,10 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) qi.tqi_aifs = 1; qi.tqi_cwmin = 0; qi.tqi_cwmax = 0; - /* NB: don't enable any interrupts */ + + if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) + qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; + return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); } EXPORT_SYMBOL(ath9k_hw_beaconq_setup); diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 11dbd1473a1..21c955609e6 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -583,8 +583,7 @@ enum ath9k_tx_queue { #define ATH9K_WME_UPSD 4 enum ath9k_tx_queue_flags { - TXQ_FLAG_TXOKINT_ENABLE = 0x0001, - TXQ_FLAG_TXERRINT_ENABLE = 0x0001, + TXQ_FLAG_TXINT_ENABLE = 0x0001, TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, TXQ_FLAG_TXURNINT_ENABLE = 0x0008, @@ -714,7 +713,6 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q); void ath9k_hw_abort_tx_dma(struct ath_hw *ah); -void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, const struct ath9k_tx_queue_info *qinfo); bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4a00806e285..38794850f00 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -118,13 +118,15 @@ void ath9k_ps_restore(struct ath_softc *sc) if (--sc->ps_usecount != 0) goto unlock; - if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) + if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) + goto unlock; + + if (sc->ps_idle) mode = ATH9K_PM_FULL_SLEEP; else if (sc->ps_enabled && !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK))) + PS_WAIT_FOR_PSPOLL_DATA))) mode = ATH9K_PM_NETWORK_SLEEP; else goto unlock; @@ -332,17 +334,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, hchan = ah->curchan; } - if (fastcc && (ah->chip_fullsleep || - !ath9k_hw_check_alive(ah))) - fastcc = false; - if (!ath_prepare_reset(sc, retry_tx, flush)) fastcc = false; ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", - hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | - CHANNEL_HT40PLUS)), - fastcc); + hchan->channel, IS_CHAN_HT40(hchan), fastcc); r = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (r) { @@ -373,12 +369,8 @@ static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, if (sc->sc_flags & SC_OP_INVALID) return -EIO; - ath9k_ps_wakeup(sc); - r = ath_reset_internal(sc, hchan, false); - ath9k_ps_restore(sc); - return r; } @@ -647,7 +639,8 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, #endif an->sta = sta; an->vif = vif; - if (sc->sc_flags & SC_OP_TXAGGR) { + + if (sta->ht_cap.ht_supported) { ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); @@ -666,7 +659,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) an->sta = NULL; #endif - if (sc->sc_flags & SC_OP_TXAGGR) + if (sta->ht_cap.ht_supported) ath_tx_node_cleanup(sc, an); } @@ -741,12 +734,7 @@ void ath9k_tasklet(unsigned long data) ath_tx_tasklet(sc); } - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) - if (status & ATH9K_INT_GENTIMER) - ath_gen_timer_isr(sc->sc_ah); - - if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI) - ath_mci_intr(sc); + ath9k_btcoex_handle_interrupt(sc, status); out: /* re-enable hardware interrupt */ @@ -1004,12 +992,8 @@ static int ath9k_start(struct ieee80211_hw *hw) curchan->center_freq); ath9k_ps_wakeup(sc); - mutex_lock(&sc->mutex); - /* setup initial channel */ - sc->chan_idx = curchan->hw_value; - init_channel = ath9k_cmn_get_curchannel(hw, ah); /* Reset SERDES registers */ @@ -1058,9 +1042,6 @@ static int ath9k_start(struct ieee80211_hw *hw) sc->sc_flags &= ~SC_OP_INVALID; sc->sc_ah->is_monitoring = false; - /* Disable BMISS interrupt when we're not associated */ - ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); - if (!ath_complete_reset(sc, false)) { r = -EIO; spin_unlock_bh(&sc->sc_pcu_lock); @@ -1081,16 +1062,7 @@ static int ath9k_start(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); - if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && - !ah->btcoex_hw.enabled) { - if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); - ath9k_hw_btcoex_enable(ah); - - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) - ath9k_btcoex_timer_resume(sc); - } + ath9k_start_btcoex(sc); if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) common->bus_ops->extn_synch_en(common); @@ -1191,13 +1163,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) /* Ensure HW is awake when we try to shut it down. */ ath9k_ps_wakeup(sc); - if (ah->btcoex_hw.enabled && - ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { - ath9k_hw_btcoex_disable(ah); - if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) - ath9k_btcoex_timer_pause(sc); - ath_mci_flush_profile(&sc->btcoex.mci); - } + ath9k_stop_btcoex(sc); spin_lock_bh(&sc->sc_pcu_lock); @@ -1303,7 +1269,6 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) iter_data->nwds++; break; default: - iter_data->nothers++; break; } } @@ -1589,12 +1554,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); - /* - * Leave this as the first check because we need to turn on the - * radio if it was disabled before prior to processing the rest - * of the changes. Likewise we must only disable the radio towards - * the end. - */ if (changed & IEEE80211_CONF_CHANGE_IDLE) { sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); if (sc->ps_idle) @@ -1793,7 +1752,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_node *an = (struct ath_node *) sta->drv_priv; - if (!(sc->sc_flags & SC_OP_TXAGGR)) + if (!sta->ht_cap.ht_supported) return; switch (cmd) { @@ -2005,7 +1964,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); - if (changed & BSS_CHANGED_BSSID) { + if (changed & BSS_CHANGED_ASSOC) { ath9k_config_bss(sc, vif); ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", @@ -2085,25 +2044,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ath_beacon_config(sc, vif); } - if (changed & BSS_CHANGED_ERP_PREAMBLE) { - ath_dbg(common, CONFIG, "BSS Changed PREAMBLE %d\n", - bss_conf->use_short_preamble); - if (bss_conf->use_short_preamble) - sc->sc_flags |= SC_OP_PREAMBLE_SHORT; - else - sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT; - } - - if (changed & BSS_CHANGED_ERP_CTS_PROT) { - ath_dbg(common, CONFIG, "BSS Changed CTS PROT %d\n", - bss_conf->use_cts_prot); - if (bss_conf->use_cts_prot && - hw->conf.channel->band != IEEE80211_BAND_5GHZ) - sc->sc_flags |= SC_OP_PROTECT_ENABLE; - else - sc->sc_flags &= ~SC_OP_PROTECT_ENABLE; - } - mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); } @@ -2161,15 +2101,10 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_RX_START: - if (!(sc->sc_flags & SC_OP_RXAGGR)) - ret = -ENOTSUPP; break; case IEEE80211_AMPDU_RX_STOP: break; case IEEE80211_AMPDU_TX_START: - if (!(sc->sc_flags & SC_OP_TXAGGR)) - return -EOPNOTSUPP; - ath9k_ps_wakeup(sc); ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (!ret) @@ -2332,6 +2267,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) struct ath_vif *avp; struct ath_buf *bf; struct ath_tx_status ts; + bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); int status; vif = sc->beacon.bslot[0]; @@ -2342,7 +2278,7 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) if (!avp->is_bslot_active) return 0; - if (!sc->beacon.tx_processed) { + if (!sc->beacon.tx_processed && !edma) { tasklet_disable(&sc->bcon_tasklet); bf = avp->av_bcbuf; diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 05c23ea4c63..29fe52d6997 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -42,24 +42,18 @@ static bool ath_mci_add_profile(struct ath_common *common, struct ath_mci_profile_info *entry; if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && - (info->type == MCI_GPM_COEX_PROFILE_VOICE)) { - ath_dbg(common, MCI, - "Too many SCO profile, failed to add new profile\n"); + (info->type == MCI_GPM_COEX_PROFILE_VOICE)) return false; - } if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && - (info->type != MCI_GPM_COEX_PROFILE_VOICE)) { - ath_dbg(common, MCI, - "Too many ACL profile, failed to add new profile\n"); + (info->type != MCI_GPM_COEX_PROFILE_VOICE)) return false; - } entry = ath_mci_find_profile(mci, info); - if (entry) + if (entry) { memcpy(entry, info, 10); - else { + } else { entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return false; @@ -68,6 +62,7 @@ static bool ath_mci_add_profile(struct ath_common *common, INC_PROF(mci, info); list_add_tail(&info->list, &mci->info); } + return true; } @@ -79,10 +74,9 @@ static void ath_mci_del_profile(struct ath_common *common, entry = ath_mci_find_profile(mci, info); - if (!entry) { - ath_dbg(common, MCI, "Profile to be deleted not found\n"); + if (!entry) return; - } + DEC_PROF(mci, entry); list_del(&entry->list); kfree(entry); @@ -177,13 +171,12 @@ static void ath_mci_update_scheme(struct ath_softc *sc) btcoex->btcoex_period *= 1000; btcoex->btcoex_no_stomp = btcoex->btcoex_period * - (100 - btcoex->duty_cycle) / 100; + (100 - btcoex->duty_cycle) / 100; ath9k_hw_btcoex_enable(sc->sc_ah); ath9k_btcoex_timer_resume(sc); } - static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) { struct ath_hw *ah = sc->sc_ah; @@ -192,42 +185,24 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) switch (opcode) { case MCI_GPM_BT_CAL_REQ: - - ath_dbg(common, MCI, "MCI received BT_CAL_REQ\n"); - if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); - } else - ath_dbg(common, MCI, "MCI State mismatches: %d\n", + } else { + ath_dbg(common, MCI, "MCI State mismatch: %d\n", ar9003_mci_state(ah, MCI_STATE_BT, NULL)); - + } break; - case MCI_GPM_BT_CAL_DONE: - - ath_dbg(common, MCI, "MCI received BT_CAL_DONE\n"); - - if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_CAL) - ath_dbg(common, MCI, "MCI error illegal!\n"); - else - ath_dbg(common, MCI, "MCI BT not in CAL state\n"); - + ar9003_mci_state(ah, MCI_STATE_BT, NULL); break; - case MCI_GPM_BT_CAL_GRANT: - - ath_dbg(common, MCI, "MCI received BT_CAL_GRANT\n"); - - /* Send WLAN_CAL_DONE for now */ - ath_dbg(common, MCI, "MCI send WLAN_CAL_DONE\n"); MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); ar9003_mci_send_message(sc->sc_ah, MCI_GPM, 0, payload, 16, false, true); break; - default: - ath_dbg(common, MCI, "MCI Unknown GPM CAL message\n"); + ath_dbg(common, MCI, "Unknown GPM CAL message\n"); break; } } @@ -247,6 +222,7 @@ static void ath_mci_process_profile(struct ath_softc *sc, btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; mci->aggr_limit = mci->num_sco ? 6 : 0; + if (NUM_PROF(mci)) { btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; @@ -262,31 +238,24 @@ static void ath_mci_process_profile(struct ath_softc *sc, static void ath_mci_process_status(struct ath_softc *sc, struct ath_mci_profile_status *status) { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; struct ath_mci_profile_info info; int i = 0, old_num_mgmt = mci->num_mgmt; /* Link status type are not handled */ - if (status->is_link) { - ath_dbg(common, MCI, "Skip link type status update\n"); + if (status->is_link) return; - } memset(&info, 0, sizeof(struct ath_mci_profile_info)); info.conn_handle = status->conn_handle; - if (ath_mci_find_profile(mci, &info)) { - ath_dbg(common, MCI, - "Skip non link state update for existing profile %d\n", - status->conn_handle); + if (ath_mci_find_profile(mci, &info)) return; - } - if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { - ath_dbg(common, MCI, "Ignore too many non-link update\n"); + + if (status->conn_handle >= ATH_MCI_MAX_PROFILE) return; - } + if (status->is_critical) __set_bit(status->conn_handle, mci->status); else @@ -314,43 +283,28 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) u32 seq_num; switch (opcode) { - case MCI_GPM_COEX_VERSION_QUERY: - ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n"); - version = ar9003_mci_state(ah, - MCI_STATE_SEND_WLAN_COEX_VERSION, NULL); + version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, + NULL); break; - case MCI_GPM_COEX_VERSION_RESPONSE: - ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n"); major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); - ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n", - major, minor); version = (major << 8) + minor; - version = ar9003_mci_state(ah, - MCI_STATE_SET_BT_COEX_VERSION, &version); + version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION, + &version); break; - case MCI_GPM_COEX_STATUS_QUERY: - ath_dbg(common, MCI, - "MCI Recv GPM COEX Status Query = 0x%02x\n", - *(rx_payload + MCI_GPM_COEX_B_WLAN_BITMAP)); - ar9003_mci_state(ah, - MCI_STATE_SEND_WLAN_CHANNELS, NULL); + ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL); break; - case MCI_GPM_COEX_BT_PROFILE_INFO: - ath_dbg(common, MCI, "MCI Recv GPM Coex BT profile info\n"); memcpy(&profile_info, (rx_payload + MCI_GPM_COEX_B_PROFILE_TYPE), 10); - if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN) - || (profile_info.type >= - MCI_GPM_COEX_PROFILE_MAX)) { - + if ((profile_info.type == MCI_GPM_COEX_PROFILE_UNKNOWN) || + (profile_info.type >= MCI_GPM_COEX_PROFILE_MAX)) { ath_dbg(common, MCI, - "illegal profile type = %d, state = %d\n", + "Illegal profile type = %d, state = %d\n", profile_info.type, profile_info.start); break; @@ -358,7 +312,6 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) ath_mci_process_profile(sc, &profile_info); break; - case MCI_GPM_COEX_BT_STATUS_UPDATE: profile_status.is_link = *(rx_payload + MCI_GPM_COEX_B_STATUS_TYPE); @@ -369,98 +322,66 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) seq_num = *((u32 *)(rx_payload + 12)); ath_dbg(common, MCI, - "MCI Recv GPM COEX BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n", + "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n", profile_status.is_link, profile_status.conn_handle, profile_status.is_critical, seq_num); ath_mci_process_status(sc, &profile_status); break; - default: - ath_dbg(common, MCI, "MCI Unknown GPM COEX message = 0x%02x\n", - opcode); + ath_dbg(common, MCI, "Unknown GPM COEX message = 0x%02x\n", opcode); break; } } -static int ath_mci_buf_alloc(struct ath_softc *sc, struct ath_mci_buf *buf) -{ - int error = 0; - - buf->bf_addr = dma_alloc_coherent(sc->dev, buf->bf_len, - &buf->bf_paddr, GFP_KERNEL); - - if (buf->bf_addr == NULL) { - error = -ENOMEM; - goto fail; - } - - return 0; - -fail: - memset(buf, 0, sizeof(*buf)); - return error; -} - -static void ath_mci_buf_free(struct ath_softc *sc, struct ath_mci_buf *buf) -{ - if (buf->bf_addr) { - dma_free_coherent(sc->dev, buf->bf_len, buf->bf_addr, - buf->bf_paddr); - memset(buf, 0, sizeof(*buf)); - } -} - int ath_mci_setup(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_mci_coex *mci = &sc->mci_coex; - int error = 0; - - if (!ATH9K_HW_CAP_MCI) - return 0; + struct ath_mci_buf *buf = &mci->sched_buf; - mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE; + buf->bf_addr = dma_alloc_coherent(sc->dev, + ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, + &buf->bf_paddr, GFP_KERNEL); - if (ath_mci_buf_alloc(sc, &mci->sched_buf)) { + if (buf->bf_addr == NULL) { ath_dbg(common, FATAL, "MCI buffer alloc failed\n"); - error = -ENOMEM; - goto fail; + return -ENOMEM; } - mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE; + memset(buf->bf_addr, MCI_GPM_RSVD_PATTERN, + ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE); - memset(mci->sched_buf.bf_addr, MCI_GPM_RSVD_PATTERN, - mci->sched_buf.bf_len); + mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE; mci->gpm_buf.bf_len = ATH_MCI_GPM_BUF_SIZE; - mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + - mci->sched_buf.bf_len; + mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len; mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len; - /* initialize the buffer */ - memset(mci->gpm_buf.bf_addr, MCI_GPM_RSVD_PATTERN, mci->gpm_buf.bf_len); - ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), mci->sched_buf.bf_paddr); -fail: - return error; + + ath_dbg(common, MCI, "MCI Initialized\n"); + + return 0; } void ath_mci_cleanup(struct ath_softc *sc) { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_hw *ah = sc->sc_ah; struct ath_mci_coex *mci = &sc->mci_coex; + struct ath_mci_buf *buf = &mci->sched_buf; - if (!ATH9K_HW_CAP_MCI) - return; + if (buf->bf_addr) + dma_free_coherent(sc->dev, + ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, + buf->bf_addr, buf->bf_paddr); - /* - * both schedule and gpm buffers will be released - */ - ath_mci_buf_free(sc, &mci->sched_buf); ar9003_mci_cleanup(ah); + + ath_dbg(common, MCI, "MCI De-Initialized\n"); } void ath_mci_intr(struct ath_softc *sc) @@ -474,19 +395,10 @@ void ath_mci_intr(struct ath_softc *sc) u32 more_data = MCI_GPM_MORE; bool skip_gpm = false; - if (!ATH9K_HW_CAP_MCI) - return; - ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { - - ar9003_mci_state(sc->sc_ah, MCI_STATE_INIT_GPM_OFFSET, NULL); - ath_dbg(common, MCI, "MCI interrupt but MCI disabled\n"); - - ath_dbg(common, MCI, - "MCI interrupt: intr = 0x%x, intr_rxmsg = 0x%x\n", - mci_int, mci_int_rxmsg); + ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); return; } @@ -499,11 +411,8 @@ void ath_mci_intr(struct ath_softc *sc) * only when BT wake up. Now they are always sent, as a * recovery method to reset BT MCI's RX alignment. */ - ath_dbg(common, MCI, "MCI interrupt send REMOTE_RESET\n"); - ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16, true, false); - ath_dbg(common, MCI, "MCI interrupt send SYS_WAKING\n"); ar9003_mci_send_message(ah, MCI_SYS_WAKING, 0, NULL, 0, true, false); @@ -513,74 +422,51 @@ void ath_mci_intr(struct ath_softc *sc) /* * always do this for recovery and 2G/5G toggling and LNA_TRANS */ - ath_dbg(common, MCI, "MCI Set BT state to AWAKE\n"); ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); } - /* Processing SYS_WAKING/SYS_SLEEPING */ if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) { - - if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) - == MCI_BT_SLEEP) - ath_dbg(common, MCI, - "MCI BT stays in sleep mode\n"); - else { - ath_dbg(common, MCI, - "MCI Set BT state to AWAKE\n"); - ar9003_mci_state(ah, - MCI_STATE_SET_BT_AWAKE, NULL); - } - } else - ath_dbg(common, MCI, "MCI BT stays in AWAKE mode\n"); + if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != + MCI_BT_SLEEP) + ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, + NULL); + } } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { - mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { - - if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) - == MCI_BT_AWAKE) - ath_dbg(common, MCI, - "MCI BT stays in AWAKE mode\n"); - else { - ath_dbg(common, MCI, - "MCI SetBT state to SLEEP\n"); + if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != + MCI_BT_AWAKE) ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, NULL); - } - } else - ath_dbg(common, MCI, "MCI BT stays in SLEEP mode\n"); + } } if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { - - ath_dbg(common, MCI, "MCI RX broken, skip GPM msgs\n"); ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); skip_gpm = true; } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { - mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET, NULL); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { - mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; while (more_data == MCI_GPM_MORE) { pgpm = mci->gpm_buf.bf_addr; - offset = ar9003_mci_state(ah, - MCI_STATE_NEXT_GPM_OFFSET, &more_data); + offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, + &more_data); if (offset == MCI_GPM_INVALID) break; @@ -591,44 +477,38 @@ void ath_mci_intr(struct ath_softc *sc) * The first dword is timer. * The real data starts from 2nd dword. */ - subtype = MCI_GPM_TYPE(pgpm); opcode = MCI_GPM_OPCODE(pgpm); - if (!skip_gpm) { - - if (MCI_GPM_IS_CAL_TYPE(subtype)) - ath_mci_cal_msg(sc, subtype, - (u8 *) pgpm); - else { - switch (subtype) { - case MCI_GPM_COEX_AGENT: - ath_mci_msg(sc, opcode, - (u8 *) pgpm); - break; - default: - break; - } + if (skip_gpm) + goto recycle; + + if (MCI_GPM_IS_CAL_TYPE(subtype)) { + ath_mci_cal_msg(sc, subtype, (u8 *)pgpm); + } else { + switch (subtype) { + case MCI_GPM_COEX_AGENT: + ath_mci_msg(sc, opcode, (u8 *)pgpm); + break; + default: + break; } } + recycle: MCI_GPM_RECYCLE(pgpm); } } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_HW_MSG_MASK) { - if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL; - if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO) { + if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_LNA_INFO) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; - ath_dbg(common, MCI, "MCI LNA_INFO\n"); - } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { - int value_dbm = ar9003_mci_state(ah, - MCI_STATE_CONT_RSSI_POWER, NULL); + MCI_STATE_CONT_RSSI_POWER, NULL); mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; @@ -636,33 +516,25 @@ void ath_mci_intr(struct ath_softc *sc) ath_dbg(common, MCI, "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", ar9003_mci_state(ah, - MCI_STATE_CONT_PRIORITY, NULL), + MCI_STATE_CONT_PRIORITY, NULL), value_dbm); else ath_dbg(common, MCI, "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n", ar9003_mci_state(ah, - MCI_STATE_CONT_PRIORITY, NULL), + MCI_STATE_CONT_PRIORITY, NULL), value_dbm); } - if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) { + if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_NACK; - ath_dbg(common, MCI, "MCI CONT_NACK\n"); - } - if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST) { + if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_RST) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_RST; - ath_dbg(common, MCI, "MCI CONT_RST\n"); - } } if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); - - if (mci_int_rxmsg & 0xfffffffe) - ath_dbg(common, MCI, "MCI not processed mci_int_rxmsg = 0x%x\n", - mci_int_rxmsg); } diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h index 29e3e51d078..c841444f53c 100644 --- a/drivers/net/wireless/ath/ath9k/mci.h +++ b/drivers/net/wireless/ath/ath9k/mci.h @@ -17,6 +17,8 @@ #ifndef MCI_H #define MCI_H +#include "ar9003_mci.h" + #define ATH_MCI_SCHED_BUF_SIZE (16 * 16) /* 16 entries, 4 dword each */ #define ATH_MCI_GPM_MAX_ENTRY 16 #define ATH_MCI_GPM_BUF_SIZE (ATH_MCI_GPM_MAX_ENTRY * 16) @@ -113,7 +115,6 @@ struct ath_mci_profile { u8 num_bdr; }; - struct ath_mci_buf { void *bf_addr; /* virtual addr of desc */ dma_addr_t bf_paddr; /* physical addr of buffer */ @@ -121,10 +122,8 @@ struct ath_mci_buf { }; struct ath_mci_coex { - atomic_t mci_cal_flag; struct ath_mci_buf sched_buf; struct ath_mci_buf gpm_buf; - u32 bt_cal_start; }; void ath_mci_flush_profile(struct ath_mci_profile *mci); diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index a427a16bb73..4f848493fec 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -567,10 +567,8 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, const struct ath_rate_table *rate_table, - u8 *mcs_set, u32 capflag) + struct ath_rateset *rateset, u32 capflag) { - struct ath_rateset *rateset = (struct ath_rateset *)mcs_set; - u8 i, j, hi = 0; /* Use intersection of working rates and valid rates */ @@ -750,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc, * If 802.11g protection is enabled, determine whether to use RTS/CTS or * just CTS. Note that this is only done for OFDM/HT unicast frames. */ - if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) && + if ((tx_info->control.vif && + tx_info->control.vif->bss_conf.use_cts_prot) && (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; @@ -1212,7 +1211,7 @@ static void ath_rc_init(struct ath_softc *sc, { struct ath_rateset *rateset = &ath_rc_priv->neg_rates; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; + struct ath_rateset *ht_mcs = &ath_rc_priv->neg_ht_rates; u8 i, j, k, hi = 0, hthi = 0; /* Initial rate table size. Will change depending @@ -1228,7 +1227,7 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_init_valid_rate_idx(ath_rc_priv); for (i = 0; i < WLAN_RC_PHY_MAX; i++) { - for (j = 0; j < MAX_TX_RATE_PHY; j++) + for (j = 0; j < RATE_TABLE_SIZE; j++) ath_rc_priv->valid_phy_rateidx[i][j] = 0; ath_rc_priv->valid_phy_ratecnt[i] = 0; } @@ -1300,12 +1299,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, return caps; } -static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, +static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta, u8 tidno) { + struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_atx_tid *txtid; - if (!(sc->sc_flags & SC_OP_TXAGGR)) + if (!sta->ht_cap.ht_supported) return false; txtid = ATH_AN_2_TID(an, tidno); @@ -1376,13 +1376,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, if (ieee80211_is_data_qos(fc) && skb_get_queue_mapping(skb) != IEEE80211_AC_VO) { u8 *qc, tid; - struct ath_node *an; qc = ieee80211_get_qos_ctl(hdr); tid = qc[0] & 0xf; - an = (struct ath_node *)sta->drv_priv; - if(ath_tx_aggr_check(sc, an, tid)) + if(ath_tx_aggr_check(sc, sta, tid)) ieee80211_start_tx_ba_session(sta, tid, 0); } } diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index b7a4bcd3eec..75f8e9b06b2 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -25,8 +25,6 @@ struct ath_softc; #define ATH_RATE_MAX 30 #define RATE_TABLE_SIZE 72 -#define MAX_TX_RATE_PHY 48 - #define RC_INVALID 0x0000 #define RC_LEGACY 0x0001 diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 7e1a91af149..f4ae3ba994a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -169,22 +169,17 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, enum ath9k_rx_qtype qtype, int size) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); - u32 nbuf = 0; + struct ath_buf *bf, *tbf; if (list_empty(&sc->rx.rxbuf)) { ath_dbg(common, QUEUE, "No free rx buf available\n"); return; } - while (!list_empty(&sc->rx.rxbuf)) { - nbuf++; - + list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) if (!ath_rx_edma_buf_link(sc, qtype)) break; - if (nbuf >= size) - break; - } } static void ath_rx_remove_buffer(struct ath_softc *sc, @@ -232,7 +227,6 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) { skb_queue_head_init(&rx_edma->rx_fifo); - skb_queue_head_init(&rx_edma->rx_buffers); rx_edma->rx_fifo_hwsize = size; } @@ -658,7 +652,9 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) } static bool ath_edma_get_buffers(struct ath_softc *sc, - enum ath9k_rx_qtype qtype) + enum ath9k_rx_qtype qtype, + struct ath_rx_status *rs, + struct ath_buf **dest) { struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; struct ath_hw *ah = sc->sc_ah; @@ -677,7 +673,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, common->rx_bufsize, DMA_FROM_DEVICE); - ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); + ret = ath9k_hw_process_rxdesc_edma(ah, rs, skb->data); if (ret == -EINPROGRESS) { /*let device gain the buffer again*/ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, @@ -690,20 +686,21 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, /* corrupt descriptor, skip this one and the following one */ list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); - skb = skb_peek(&rx_edma->rx_fifo); - if (!skb) - return true; - bf = SKB_CB_ATHBUF(skb); - BUG_ON(!bf); + skb = skb_peek(&rx_edma->rx_fifo); + if (skb) { + bf = SKB_CB_ATHBUF(skb); + BUG_ON(!bf); - __skb_unlink(skb, &rx_edma->rx_fifo); - list_add_tail(&bf->list, &sc->rx.rxbuf); - ath_rx_edma_buf_link(sc, qtype); - return true; + __skb_unlink(skb, &rx_edma->rx_fifo); + list_add_tail(&bf->list, &sc->rx.rxbuf); + ath_rx_edma_buf_link(sc, qtype); + } else { + bf = NULL; + } } - skb_queue_tail(&rx_edma->rx_buffers, skb); + *dest = bf; return true; } @@ -711,18 +708,15 @@ static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, struct ath_rx_status *rs, enum ath9k_rx_qtype qtype) { - struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; - struct sk_buff *skb; - struct ath_buf *bf; + struct ath_buf *bf = NULL; - while (ath_edma_get_buffers(sc, qtype)); - skb = __skb_dequeue(&rx_edma->rx_buffers); - if (!skb) - return NULL; + while (ath_edma_get_buffers(sc, qtype, rs, &bf)) { + if (!bf) + continue; - bf = SKB_CB_ATHBUF(skb); - ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); - return bf; + return bf; + } + return NULL; } static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, @@ -954,6 +948,7 @@ static void ath9k_process_rssi(struct ath_common *common, struct ath_softc *sc = hw->priv; struct ath_hw *ah = common->ah; int last_rssi; + int rssi = rx_stats->rs_rssi; if (!rx_stats->is_mybeacon || ((ah->opmode != NL80211_IFTYPE_STATION) && @@ -965,13 +960,12 @@ static void ath9k_process_rssi(struct ath_common *common, last_rssi = sc->last_rssi; if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) - rx_stats->rs_rssi = ATH_EP_RND(last_rssi, - ATH_RSSI_EP_MULTIPLIER); - if (rx_stats->rs_rssi < 0) - rx_stats->rs_rssi = 0; + rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); + if (rssi < 0) + rssi = 0; /* Update Beacon RSSI, this is used by ANI. */ - ah->stats.avgbrssi = rx_stats->rs_rssi; + ah->stats.avgbrssi = rssi; } /* @@ -988,8 +982,6 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, { struct ath_hw *ah = common->ah; - memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); - /* * everything but the rate is checked here, the rate check is done * separately to avoid doing two lookups for a rate for each frame. @@ -1011,6 +1003,8 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, rx_status->signal = ah->noise + rx_stats->rs_rssi; rx_status->antenna = rx_stats->rs_antenna; rx_status->flag |= RX_FLAG_MACTIME_MPDU; + if (rx_stats->rs_moreaggr) + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; return 0; } @@ -1845,6 +1839,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) if (sc->sc_flags & SC_OP_RXFLUSH) goto requeue_drop_frag; + memset(rxs, 0, sizeof(struct ieee80211_rx_status)); + rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; if (rs.rs_tstamp > tsf_lower && unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 6e2f18861f5..458f81b4a7c 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -797,7 +797,6 @@ #define AR_SREV_VERSION_9580 0x1C0 #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ #define AR_SREV_VERSION_9462 0x280 -#define AR_SREV_REVISION_9462_10 0 #define AR_SREV_REVISION_9462_20 2 #define AR_SREV_5416(_ah) \ @@ -898,10 +897,6 @@ #define AR_SREV_9462(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) -#define AR_SREV_9462_10(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_10)) - #define AR_SREV_9462_20(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) @@ -1156,6 +1151,7 @@ enum { #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) #define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 +#define AR_ENT_OTP_49GHZ_DISABLE 0x00100000 #define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000 #define AR_CH0_BB_DPLL1 0x16180 diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3182408ffe3..834e6bc45e8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -647,9 +647,8 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; - struct ath_mci_profile *mci = &sc->btcoex.mci; u32 max_4ms_framelen, frmlen; - u16 aggr_limit, legacy = 0; + u16 aggr_limit, bt_aggr_limit, legacy = 0; int i; skb = bf->bf_mpdu; @@ -694,14 +693,14 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) return 0; - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) - aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; - else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) - aggr_limit = min((max_4ms_framelen * 3) / 8, - (u32)ATH_AMPDU_LIMIT_MAX); - else - aggr_limit = min(max_4ms_framelen, - (u32)ATH_AMPDU_LIMIT_MAX); + aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_MAX); + + /* + * Override the default aggregation limit for BTCOEX. + */ + bt_aggr_limit = ath9k_btcoex_aggr_limit(sc, max_4ms_framelen); + if (bt_aggr_limit) + aggr_limit = bt_aggr_limit; /* * h/w can accept aggregates up to 16 bit lengths (65535). @@ -956,7 +955,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, */ rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); info->rtscts_rate = rate->hw_value; - if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) + + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) info->rtscts_rate |= rate->hw_value_short; for (i = 0; i < 4; i++) { @@ -1291,14 +1292,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid an = (struct ath_node *)sta->drv_priv; - if (sc->sc_flags & SC_OP_TXAGGR) { - txtid = ATH_AN_2_TID(an, tid); - txtid->baw_size = - IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; - txtid->state |= AGGR_ADDBA_COMPLETE; - txtid->state &= ~AGGR_ADDBA_PROGRESS; - ath_tx_resume_tid(sc, txtid); - } + txtid = ATH_AN_2_TID(an, tid); + txtid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; + txtid->state |= AGGR_ADDBA_COMPLETE; + txtid->state &= ~AGGR_ADDBA_PROGRESS; + ath_tx_resume_tid(sc, txtid); } /********************/ @@ -1357,8 +1355,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) * based intr on the EOSP frames. */ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { - qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | - TXQ_FLAG_TXERRINT_ENABLE; + qi.tqi_qflags = TXQ_FLAG_TXINT_ENABLE; } else { if (qtype == ATH9K_TX_QUEUE_UAPSD) qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; @@ -1524,7 +1521,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); /* flush any pending frames if aggregation is enabled */ - if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && !retry_tx) ath_txq_drain_pending_buffers(sc, txq); ath_txq_unlock_complete(sc, txq); @@ -1872,7 +1869,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb, struct ath_buf *bf; u8 tidno; - if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an && + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) && txctl->an && ieee80211_is_data_qos(hdr->frame_control)) { tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; @@ -2142,7 +2139,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, } else ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_txq_schedule(sc, txq); } @@ -2167,7 +2164,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (list_empty(&txq->axq_q)) { txq->axq_link = NULL; - if (sc->sc_flags & SC_OP_TXAGGR) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_txq_schedule(sc, txq); break; } @@ -2264,10 +2261,9 @@ static void ath_tx_complete_poll_work(struct work_struct *work) void ath_tx_tasklet(struct ath_softc *sc) { + struct ath_hw *ah = sc->sc_ah; + u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs; int i; - u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1); - - ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) @@ -2297,9 +2293,12 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) break; } - /* Skip beacon completions */ - if (ts.qid == sc->beacon.beaconq) + /* Process beacon completions separately */ + if (ts.qid == sc->beacon.beaconq) { + sc->beacon.tx_processed = true; + sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); continue; + } txq = &sc->tx.txq[ts.qid]; diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 6cfbb419e2f..0cea20e3e25 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); int carl9170_disable_key(struct ar9170 *ar, const u8 id); +int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel); /* RX */ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); @@ -593,7 +594,6 @@ int carl9170_get_noisefloor(struct ar9170 *ar); /* FW */ int carl9170_parse_firmware(struct ar9170 *ar); -int carl9170_fw_fix_eeprom(struct ar9170 *ar); extern struct ieee80211_rate __carl9170_ratetable[]; extern int modparam_noht; diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 3de61adacd3..cffde8d9a52 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -389,39 +389,6 @@ carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len) return (void *)&fw_data[scan - found]; } -int carl9170_fw_fix_eeprom(struct ar9170 *ar) -{ - const struct carl9170fw_fix_desc *fix_desc = NULL; - unsigned int i, n, off; - u32 *data = (void *)&ar->eeprom; - - fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC, - sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER); - - if (!fix_desc) - return 0; - - n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) / - sizeof(struct carl9170fw_fix_entry); - - for (i = 0; i < n; i++) { - off = le32_to_cpu(fix_desc->data[i].address) - - AR9170_EEPROM_START; - - if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) { - dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i); - continue; - } - - data[off / sizeof(*data)] &= - le32_to_cpu(fix_desc->data[i].mask); - data[off / sizeof(*data)] |= - le32_to_cpu(fix_desc->data[i].value); - } - - return 0; -} - int carl9170_parse_firmware(struct ar9170 *ar) { const struct carl9170fw_desc_head *fw_desc = NULL; diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index dfda9197099..53415bfd8be 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id) return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, sizeof(key), (u8 *)&key, 0, NULL); } + +int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) +{ + unsigned int power, chains; + + if (ar->eeprom.tx_mask != 1) + chains = AR9170_TX_PHY_TXCHAIN_2; + else + chains = AR9170_TX_PHY_TXCHAIN_1; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + power = ar->power_2G_ofdm[0] & 0x3f; + break; + case IEEE80211_BAND_5GHZ: + power = ar->power_5G_leg[0] & 0x3f; + break; + default: + BUG_ON(1); + } + + power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, + 0x3c1e | power << 20 | chains << 26); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, + power << 5 | chains << 11 | + power << 21 | chains << 27); + carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, + power << 5 | chains << 11 | + power << 21 | chains << 27); + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index db774212161..8d2523b3f72 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } - if (changed & IEEE80211_CONF_CHANGE_POWER) { - /* TODO */ - err = 0; - } - if (changed & IEEE80211_CONF_CHANGE_SMPS) { /* TODO */ err = 0; @@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } + if (changed & IEEE80211_CONF_CHANGE_POWER) { + err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); + if (err) + goto out; + } + out: mutex_unlock(&ar->mutex); return err; @@ -1796,6 +1797,9 @@ void *carl9170_alloc(size_t priv_size) ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + /* As IBSS Encryption is software-based, IBSS RSN is supported. */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; return ar; err_nomem: @@ -1931,10 +1935,6 @@ int carl9170_register(struct ar9170 *ar) if (err) return err; - err = carl9170_fw_fix_eeprom(ar); - if (err) - return err; - err = carl9170_parse_eeprom(ar); if (err) return err; diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 472efc7e340..b72c09cf43a 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) #undef EDGES } -static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, - enum carl9170_bw bw) +static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw) { struct ar9170_calibration_target_power_legacy *ctpl; struct ar9170_calibration_target_power_ht *ctph; u8 *ctpres; int ntargets; int idx, i, n; - u8 ackpower, ackchains, f; + u8 f; u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; if (freq < 3000) @@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, /* calc. conformance test limits and apply to ar->power*[] */ carl9170_calc_ctl(ar, freq, bw); - - /* set ACK/CTS TX power */ - carl9170_regwrite_begin(ar); - - if (ar->eeprom.tx_mask != 1) - ackchains = AR9170_TX_PHY_TXCHAIN_2; - else - ackchains = AR9170_TX_PHY_TXCHAIN_1; - - if (freq < 3000) - ackpower = ar->power_2G_ofdm[0] & 0x3f; - else - ackpower = ar->power_5G_leg[0] & 0x3f; - - carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, - 0x3c1e | ackpower << 20 | ackchains << 26); - carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, - ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, - ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); } int carl9170_get_noisefloor(struct ar9170 *ar) @@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, if (err) return err; - err = carl9170_set_power_cal(ar, channel->center_freq, bw); + carl9170_set_power_cal(ar, channel->center_freq, bw); + + err = carl9170_set_mac_tpc(ar, channel); if (err) return err; diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index bbc813dee98..aed305177af 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, else *chains = AR9170_TX_PHY_TXCHAIN_2; } + + *tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2); } static __le32 carl9170_tx_physet(struct ar9170 *ar, @@ -1245,7 +1247,7 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) tx_info = IEEE80211_SKB_CB(skb); if (unlikely(sta_info->sleeping) && - !(tx_info->flags & (IEEE80211_TX_CTL_POLL_RESPONSE | + !(tx_info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER | IEEE80211_TX_CTL_CLEAR_PS_FILT))) { rcu_read_unlock(); diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c index d9218fe0203..ea2c737138d 100644 --- a/drivers/net/wireless/ath/main.c +++ b/drivers/net/wireless/ath/main.c @@ -57,7 +57,8 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, } EXPORT_SYMBOL(ath_rxbuf_alloc); -void ath_printk(const char *level, const char *fmt, ...) +void ath_printk(const char *level, const struct ath_common* common, + const char *fmt, ...) { struct va_format vaf; va_list args; @@ -67,7 +68,11 @@ void ath_printk(const char *level, const char *fmt, ...) vaf.fmt = fmt; vaf.va = &args; - printk("%sath: %pV", level, &vaf); + if (common && common->hw && common->hw->wiphy) + printk("%sath: %s: %pV", + level, wiphy_name(common->hw->wiphy), &vaf); + else + printk("%sath: %pV", level, &vaf); va_end(args); } diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 7e45ca2e78e..3010cee7b95 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1533,10 +1533,9 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, /* Create the network device object. */ dev = alloc_etherdev(sizeof(*priv)); - if (!dev) { - printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n"); + if (!dev) return NULL; - } + if (dev_alloc_name(dev, dev->name) < 0) { printk(KERN_ERR "atmel: Couldn't get name!\n"); goto err_out_free; diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 16e8f805815..67c13af6f20 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -932,6 +932,9 @@ struct b43_wl { /* Flag that implement the queues stopping. */ bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; + /* firmware loading work */ + struct work_struct firmware_load; + /* The device LEDs. */ struct b43_leds leds; @@ -999,6 +1002,12 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) dev->dev->write16(dev->dev, offset, value); } +static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask, + u16 set) +{ + b43_write16(dev, offset, (b43_read16(dev, offset) & mask) | set); +} + static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) { return dev->dev->read32(dev->dev, offset); @@ -1009,6 +1018,12 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) dev->dev->write32(dev->dev, offset, value); } +static inline void b43_maskset32(struct b43_wldev *dev, u16 offset, u32 mask, + u32 set) +{ + b43_write32(dev, offset, (b43_read32(dev, offset) & mask) | set); +} + static inline void b43_block_read(struct b43_wldev *dev, void *buffer, size_t count, u16 offset, u8 reg_width) { diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 23ffb1b9a86..c79e6638c88 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -580,22 +580,14 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) static void b43_time_lock(struct b43_wldev *dev) { - u32 macctl; - - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl |= B43_MACCTL_TBTTHOLD; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_TBTTHOLD); /* Commit the write */ b43_read32(dev, B43_MMIO_MACCTL); } static void b43_time_unlock(struct b43_wldev *dev) { - u32 macctl; - - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_TBTTHOLD; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_TBTTHOLD, 0); /* Commit the write */ b43_read32(dev, B43_MMIO_MACCTL); } @@ -2398,8 +2390,14 @@ error: return err; } -static int b43_request_firmware(struct b43_wldev *dev) +static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl); +static void b43_one_core_detach(struct b43_bus_dev *dev); + +static void b43_request_firmware(struct work_struct *work) { + struct b43_wl *wl = container_of(work, + struct b43_wl, firmware_load); + struct b43_wldev *dev = wl->current_dev; struct b43_request_fw_context *ctx; unsigned int i; int err; @@ -2407,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev) ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) - return -ENOMEM; + return; ctx->dev = dev; ctx->req_type = B43_FWTYPE_PROPRIETARY; err = b43_try_request_fw(ctx); if (!err) - goto out; /* Successfully loaded it. */ - err = ctx->fatal_failure; - if (err) + goto start_ieee80211; /* Successfully loaded it. */ + /* Was fw version known? */ + if (ctx->fatal_failure) goto out; + /* proprietary fw not found, try open source */ ctx->req_type = B43_FWTYPE_OPENSOURCE; err = b43_try_request_fw(ctx); if (!err) - goto out; /* Successfully loaded it. */ - err = ctx->fatal_failure; - if (err) + goto start_ieee80211; /* Successfully loaded it. */ + if(ctx->fatal_failure) goto out; /* Could not find a usable firmware. Print the errors. */ @@ -2433,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev) b43err(dev->wl, errmsg); } b43_print_fw_helptext(dev->wl, 1); - err = -ENOENT; + goto out; + +start_ieee80211: + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + b43_leds_register(wl->current_dev); + goto out; + +err_one_core_detach: + b43_one_core_detach(dev->dev); out: kfree(ctx); - return err; } static int b43_upload_microcode(struct b43_wldev *dev) @@ -2487,10 +2494,8 @@ static int b43_upload_microcode(struct b43_wldev *dev) b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL); /* Start the microcode PSM */ - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_JMP0; - macctl |= B43_MACCTL_PSM_RUN; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_JMP0, + B43_MACCTL_PSM_RUN); /* Wait for the microcode to load and respond */ i = 0; @@ -2590,10 +2595,9 @@ static int b43_upload_microcode(struct b43_wldev *dev) return 0; error: - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_RUN; - macctl |= B43_MACCTL_PSM_JMP0; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + /* Stop the microcode PSM. */ + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, + B43_MACCTL_PSM_JMP0); return err; } @@ -2708,11 +2712,8 @@ static int b43_gpio_init(struct b43_wldev *dev) struct ssb_device *gpiodev; u32 mask, set; - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_GPOUTSMSK); - - b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) - | 0x000F); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); + b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); mask = 0x0000001F; set = 0x0000000F; @@ -2720,6 +2721,8 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0060; set |= 0x0060; } + if (dev->dev->chip_id == 0x5354) + set &= 0xff02; if (0 /* FIXME: conditional unknown */ ) { b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) @@ -2800,9 +2803,7 @@ void b43_mac_enable(struct b43_wldev *dev) dev->mac_suspended--; B43_WARN_ON(dev->mac_suspended < 0); if (dev->mac_suspended == 0) { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_ENABLED); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_ENABLED); b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_MAC_SUSPENDED); /* Commit writes */ @@ -2823,9 +2824,7 @@ void b43_mac_suspend(struct b43_wldev *dev) if (dev->mac_suspended == 0) { b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_ENABLED); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_ENABLED, 0); /* force pci to flush the write */ b43_read32(dev, B43_MMIO_MACCTL); for (i = 35; i; i--) { @@ -2931,15 +2930,10 @@ static void b43_adjust_opmode(struct b43_wldev *dev) * so always disable it. If we want to implement PMQ, * we need to enable it here (clear DISCPMQ) in AP mode. */ - if (0 /* ctl & B43_MACCTL_AP */) { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_DISCPMQ); - } else { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_DISCPMQ); - } + if (0 /* ctl & B43_MACCTL_AP */) + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_DISCPMQ, 0); + else + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_DISCPMQ); } static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm) @@ -3044,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev) macctl |= B43_MACCTL_INFRA; b43_write32(dev, B43_MMIO_MACCTL, macctl); - err = b43_request_firmware(dev); - if (err) - goto out; err = b43_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -3083,10 +3074,8 @@ static int b43_chip_init(struct b43_wldev *dev) if (dev->dev->core_rev < 5) b43_write32(dev, 0x010C, 0x01000000); - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_INFRA); - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_INFRA); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_INFRA, 0); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_INFRA); /* Probe Response Timeout value */ /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */ @@ -4178,6 +4167,7 @@ redo: mutex_unlock(&wl->mutex); cancel_delayed_work_sync(&dev->periodic_work); cancel_work_sync(&wl->tx_work); + cancel_work_sync(&wl->firmware_load); mutex_lock(&wl->mutex); dev = wl->current_dev; if (!dev || b43_status(dev) < B43_STAT_STARTED) { @@ -4564,8 +4554,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev) /* Locking: wl->mutex */ static void b43_wireless_core_exit(struct b43_wldev *dev) { - u32 macctl; - B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED); if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) return; @@ -4576,10 +4564,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) b43_set_status(dev, B43_STAT_UNINIT); /* Stop the microcode PSM. */ - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_RUN; - macctl |= B43_MACCTL_PSM_JMP0; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, + B43_MACCTL_PSM_JMP0); b43_dma_free(dev); b43_pio_free(dev); @@ -5341,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core) if (err) goto bcma_err_wireless_exit; - err = ieee80211_register_hw(wl->hw); - if (err) - goto bcma_err_one_core_detach; - b43_leds_register(wl->current_dev); + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43_request_firmware); + schedule_work(&wl->firmware_load); bcma_out: return err; -bcma_err_one_core_detach: - b43_one_core_detach(dev); bcma_err_wireless_exit: ieee80211_free_hw(wl->hw); return err; @@ -5417,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - b43_leds_register(wl->current_dev); - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43_request_firmware); + schedule_work(&wl->firmware_load); out: return err; - err_one_core_detach: - b43_one_core_detach(dev); err_wireless_exit: if (first) b43_wireless_exit(dev, wl); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index bf5a4385535..108118820b3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -85,22 +85,11 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev) (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ -static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */ +static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev) { - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (dev->phy.rev >= 6) { - if (dev->dev->chip_id == 47162) - return txpwrctrl_tx_gain_ipa_rev5; - return txpwrctrl_tx_gain_ipa_rev6; - } else if (dev->phy.rev >= 5) { - return txpwrctrl_tx_gain_ipa_rev5; - } else { - return txpwrctrl_tx_gain_ipa; - } - } else { - return txpwrctrl_tx_gain_ipa_5g; - } + return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >> + B43_NPHY_RFSEQCA_RXEN_SHIFT; } /************************************************** @@ -229,7 +218,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, reg = (i == 0) ? B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; - b43_phy_mask(dev, reg, 0xFBFF); + b43_phy_set(dev, reg, 0x400); switch (field) { case 0: @@ -245,7 +234,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START); for (j = 0; j < 100; j++) { - if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { + if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) { j = 0; break; } @@ -264,7 +253,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); for (j = 0; j < 100; j++) { - if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { + if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) { j = 0; break; } @@ -1231,12 +1220,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, u16 s[2]; if (dev->phy.rev >= 3) { - save_regs_phy[0] = b43_phy_read(dev, + save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); + save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); + save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1); - save_regs_phy[1] = b43_phy_read(dev, + save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2); - save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); - save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); @@ -1285,12 +1274,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); if (dev->phy.rev >= 3) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, - save_regs_phy[0]); + save_regs_phy[2]); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, - save_regs_phy[1]); - b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]); - b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]); + save_regs_phy[3]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); @@ -1308,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, return out; } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ +static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + u16 saved_regs_phy_rfctl[2]; + u16 saved_regs_phy[13]; + u16 regs_to_store[] = { + B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER, + B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2, + B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER, + B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1, + B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2, + B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2 + }; + + u16 class; + + u16 clip_state[2]; + u16 clip_off[2] = { 0xFFFF, 0xFFFF }; + + u8 vcm_final = 0; + s8 offset[4]; + s32 results[8][4] = { }; + s32 results_min[4] = { }; + s32 poll_results[4] = { }; + + u16 *rssical_radio_regs = NULL; + u16 *rssical_phy_regs = NULL; + + u16 r; /* routing */ + u8 rx_core_state; + u8 core, i, j; + + class = b43_nphy_classifier(dev, 0, 0); + b43_nphy_classifier(dev, 7, 4); + b43_nphy_read_clip_detection(dev, clip_state); + b43_nphy_write_clip_detection(dev, clip_off); + + saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); + saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); + for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) + saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); + + b43_nphy_rf_control_intc_override(dev, 0, 0, 7); + b43_nphy_rf_control_intc_override(dev, 1, 1, 7); + b43_nphy_rf_control_override(dev, 0x1, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x2, 1, 0, false); + b43_nphy_rf_control_override(dev, 0x80, 1, 0, false); + b43_nphy_rf_control_override(dev, 0x40, 1, 0, false); + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + b43_nphy_rf_control_override(dev, 0x20, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x10, 1, 0, false); + } else { + b43_nphy_rf_control_override(dev, 0x10, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x20, 1, 0, false); + } + + rx_core_state = b43_nphy_get_rx_core_state(dev); + for (core = 0; core < 2; core++) { + if (!(rx_core_state & (1 << core))) + continue; + r = core ? B2056_RX1 : B2056_RX0; + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2); + for (i = 0; i < 8; i++) { + b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, + i << 2); + b43_nphy_poll_rssi(dev, 2, results[i], 8); + } + for (i = 0; i < 4; i++) { + s32 curr; + s32 mind = 40; + s32 minpoll = 249; + u8 minvcm = 0; + if (2 * core != i) + continue; + for (j = 0; j < 8; j++) { + curr = results[j][i] * results[j][i] + + results[j][i + 1] * results[j][i]; + if (curr < mind) { + mind = curr; + minvcm = j; + } + if (results[j][i] < minpoll) + minpoll = results[j][i]; + } + vcm_final = minvcm; + results_min[i] = minpoll; + } + b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, + vcm_final << 2); + for (i = 0; i < 4; i++) { + if (core != i / 2) + continue; + offset[i] = -results[vcm_final][i]; + if (offset[i] < 0) + offset[i] = -((abs(offset[i]) + 4) / 8); + else + offset[i] = (offset[i] + 4) / 8; + if (results_min[i] == 248) + offset[i] = -32; + b43_nphy_scale_offset_rssi(dev, 0, offset[i], + (i / 2 == 0) ? 1 : 2, + (i % 2 == 0) ? 0 : 1, + 2); + } + } + for (core = 0; core < 2; core++) { + if (!(rx_core_state & (1 << core))) + continue; + for (i = 0; i < 2; i++) { + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i); + b43_nphy_poll_rssi(dev, i, poll_results, 8); + for (j = 0; j < 4; j++) { + if (j / 2 == core) + offset[j] = 232 - poll_results[j]; + if (offset[j] < 0) + offset[j] = -(abs(offset[j] + 4) / 8); + else + offset[j] = (offset[j] + 4) / 8; + b43_nphy_scale_offset_rssi(dev, 0, + offset[2 * core], core + 1, j % 2, i); + } + } + } + + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]); + + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); + + b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); + + b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); + + for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) + b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]); + + /* Store for future configuration */ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; + rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; + } else { + rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; + rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; + } + rssical_radio_regs[0] = b43_radio_read(dev, 0x602B); + rssical_radio_regs[0] = b43_radio_read(dev, 0x702B); + rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z); + rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z); + rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z); + rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z); + rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X); + rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X); + rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X); + rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X); + rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y); + rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y); + rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y); + rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y); + + /* Remember for which channel we store configuration */ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq; + else + nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq; + + /* End of calibration, restore configuration */ + b43_nphy_classifier(dev, 7, class); + b43_nphy_write_clip_detection(dev, clip_state); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) { @@ -1472,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) b43_nphy_reset_cca(dev); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ -static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) -{ - /* TODO */ -} - /* * RSSI Calibration * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal @@ -2229,27 +2392,12 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) */ for (i = 0; i < 2; i++) { - if (dev->phy.rev >= 3) { - if (b43_nphy_ipa(dev)) { - txgain = *(b43_nphy_get_ipa_gain_table(dev) + - txpi[i]); - } else if (b43_current_band(dev->wl) == - IEEE80211_BAND_5GHZ) { - /* FIXME: use 5GHz tables */ - txgain = - b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; - } else { - if (dev->phy.rev >= 5 && - sprom->fem.ghz5.extpa_gain == 3) - ; /* FIXME: 5GHz_txgain_HiPwrEPA */ - txgain = - b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; - } + txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]); + + if (dev->phy.rev >= 3) radio_gain = (txgain >> 16) & 0x1FFFF; - } else { - txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]]; + else radio_gain = (txgain >> 16) & 0x1FFF; - } if (dev->phy.rev >= 7) dac_gain = (txgain >> 8) & 0x7; @@ -2420,55 +2568,252 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev) nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF; } -static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) +/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */ +static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev) { - struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = dev->phy.n; - const u32 *table = NULL; -#if 0 - TODO: b43_ntab_papd_pga_gain_delta_ipa_2* - u32 rfpwr_offset; - u8 pga_gain; - int i; -#endif + u8 idx, delta; + u8 i, stf_mode; - if (phy->rev >= 3) { - if (b43_nphy_ipa(dev)) { - table = b43_nphy_get_ipa_gain_table(dev); + for (i = 0; i < 4; i++) + nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i]; + + for (stf_mode = 0; stf_mode < 4; stf_mode++) { + delta = 0; + switch (stf_mode) { + case 0: + if (dev->phy.is_40mhz && dev->phy.rev >= 5) { + idx = 68; + } else { + delta = 1; + idx = dev->phy.is_40mhz ? 52 : 4; + } + break; + case 1: + idx = dev->phy.is_40mhz ? 76 : 28; + break; + case 2: + idx = dev->phy.is_40mhz ? 84 : 36; + break; + case 3: + idx = dev->phy.is_40mhz ? 92 : 44; + break; + } + + for (i = 0; i < 20; i++) { + nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] = + nphy->tx_power_offset[idx]; + if (i == 0) + idx += delta; + if (i == 14) + idx += 1 - delta; + if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 || + i == 13) + idx += 1; + } + } +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */ +static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + s16 a1[2], b0[2], b1[2]; + u8 idle[2]; + s8 target[2]; + s32 num, den, pwr; + u32 regval[64]; + + u16 freq = dev->phy.channel_freq; + u16 tmp; + u16 r; /* routing */ + u8 i, c; + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000); + b43_read32(dev, B43_MMIO_MACCTL); + udelay(1); + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN); + if (dev->phy.rev >= 3) + b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF); + else + b43_phy_set(dev, B43_NPHY_TXPCTL_CMD, + B43_NPHY_TXPCTL_CMD_PCTLEN); + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) + b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0); + + if (sprom->revision < 4) { + idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g; + idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g; + target[0] = target[1] = 52; + a1[0] = a1[1] = -424; + b0[0] = b0[1] = 5612; + b1[0] = b1[1] = -1393; + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g; + target[c] = sprom->core_pwr_info[c].maxpwr_2g; + a1[c] = sprom->core_pwr_info[c].pa_2g[0]; + b0[c] = sprom->core_pwr_info[c].pa_2g[1]; + b1[c] = sprom->core_pwr_info[c].pa_2g[2]; + } + } else if (freq >= 4900 && freq < 5100) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5gl; + a1[c] = sprom->core_pwr_info[c].pa_5gl[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gl[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gl[2]; + } + } else if (freq >= 5100 && freq < 5500) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5g; + a1[c] = sprom->core_pwr_info[c].pa_5g[0]; + b0[c] = sprom->core_pwr_info[c].pa_5g[1]; + b1[c] = sprom->core_pwr_info[c].pa_5g[2]; + } + } else if (freq >= 5500) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5gh; + a1[c] = sprom->core_pwr_info[c].pa_5gh[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gh[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gh[2]; + } } else { - if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { - if (phy->rev == 3) - table = b43_ntab_tx_gain_rev3_5ghz; - if (phy->rev == 4) - table = b43_ntab_tx_gain_rev4_5ghz; - else - table = b43_ntab_tx_gain_rev5plus_5ghz; + idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g; + idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g; + target[0] = target[1] = 52; + a1[0] = a1[1] = -424; + b0[0] = b0[1] = 5612; + b1[0] = b1[1] = -1393; + } + } + /* target[0] = target[1] = nphy->tx_power_max; */ + + if (dev->phy.rev >= 3) { + if (sprom->fem.ghz2.tssipos) + b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000); + if (dev->phy.rev >= 7) { + for (c = 0; c < 2; c++) { + r = c ? 0x190 : 0x170; + if (b43_nphy_ipa(dev)) + b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC); + } + } else { + if (b43_nphy_ipa(dev)) { + tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; + b43_radio_write(dev, + B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp); + b43_radio_write(dev, + B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp); } else { - table = b43_ntab_tx_gain_rev3plus_2ghz; + b43_radio_write(dev, + B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11); + b43_radio_write(dev, + B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11); } } + } + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000); + b43_read32(dev, B43_MMIO_MACCTL); + udelay(1); + } + + if (dev->phy.rev >= 7) { + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x19); + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19); } else { - table = b43_ntab_tx_gain_rev0_1_2; + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x40); + if (dev->phy.rev > 1) + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40); + } + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) + b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0); + + b43_phy_write(dev, B43_NPHY_TXPCTL_N, + 0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT | + 3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT); + b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI, + idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT | + idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT | + B43_NPHY_TXPCTL_ITSSI_BINF); + b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR, + target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT | + target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT); + + for (c = 0; c < 2; c++) { + for (i = 0; i < 64; i++) { + num = 8 * (16 * b0[c] + b1[c] * i); + den = 32768 + a1[c] * i; + pwr = max((4 * num + den / 2) / den, -8); + if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1))) + pwr = max(pwr, target[c] + 1); + regval[i] = pwr; + } + b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval); } + + b43_nphy_tx_prepare_adjusted_power_table(dev); + /* + b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl); + b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl); + */ + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); +} + +static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + const u32 *table = NULL; + u32 rfpwr_offset; + u8 pga_gain; + int i; + + table = b43_nphy_get_tx_gain_table(dev); b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table); if (phy->rev >= 3) { #if 0 nphy->gmval = (table[0] >> 16) & 0x7000; +#endif for (i = 0; i < 128; i++) { pga_gain = (table[i] >> 24) & 0xF; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; + rfpwr_offset = + b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; else - rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain]; + rfpwr_offset = + 0; /* FIXME */ b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset); b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset); } -#endif } } @@ -3139,32 +3484,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) B43_NPHY_TXPCTL_STAT_BIDX_SHIFT; for (i = 0; i < 2; ++i) { + table = b43_nphy_get_tx_gain_table(dev); if (dev->phy.rev >= 3) { - enum ieee80211_band band = - b43_current_band(dev->wl); - - if (b43_nphy_ipa(dev)) { - table = b43_nphy_get_ipa_gain_table(dev); - } else { - if (band == IEEE80211_BAND_5GHZ) { - if (dev->phy.rev == 3) - table = b43_ntab_tx_gain_rev3_5ghz; - else if (dev->phy.rev == 4) - table = b43_ntab_tx_gain_rev4_5ghz; - else - table = b43_ntab_tx_gain_rev5plus_5ghz; - } else { - table = b43_ntab_tx_gain_rev3plus_2ghz; - } - } - target.ipa[i] = (table[index[i]] >> 16) & 0xF; target.pad[i] = (table[index[i]] >> 20) & 0xF; target.pga[i] = (table[index[i]] >> 24) & 0xF; target.txgm[i] = (table[index[i]] >> 28) & 0xF; } else { - table = b43_ntab_tx_gain_rev0_1_2; - target.ipa[i] = (table[index[i]] >> 16) & 0x3; target.pad[i] = (table[index[i]] >> 18) & 0x3; target.pga[i] = (table[index[i]] >> 20) & 0x7; @@ -3968,13 +4294,10 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) #endif } - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) & - ~B43_MACCTL_GPOUTSMSK); - b43_write16(dev, B43_MMIO_GPIO_MASK, - b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00); - b43_write16(dev, B43_MMIO_GPIO_CONTROL, - b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); + b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00); + b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF), + 0); if (init) { b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); @@ -4110,7 +4433,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_nphy_tx_power_ctrl(dev, false); b43_nphy_tx_power_fix(dev); b43_nphy_tx_power_ctl_idle_tssi(dev); - /* TODO N PHY TX Power Control Setup */ + b43_nphy_tx_power_ctl_setup(dev); b43_nphy_tx_gain_table_upload(dev); if (nphy->phyrxchain != 3) @@ -4530,8 +4853,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, { check_phyreg(dev, reg); b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); - b43_write16(dev, B43_MMIO_PHY_DATA, - (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); + b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); } static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 5de8f74cc02..fd12b386fea 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -798,6 +798,7 @@ struct b43_phy_n { bool txpwrctrl; bool pwg_gain_5ghz; u8 tx_pwr_idx[2]; + s8 tx_power_offset[101]; u16 adj_pwr_tbl[84]; u16 txcal_bbmult; u16 txiqlocal_bestc[11]; diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index f7def13524d..f0d8377429c 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2214,7 +2214,7 @@ static const u16 b43_ntab_antswctl2g_r3[4][32] = { }; /* TX gain tables */ -const u32 b43_ntab_tx_gain_rev0_1_2[] = { +static const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844, @@ -2249,7 +2249,7 @@ const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03801442, 0x03801344, 0x03801342, 0x00002b00, }; -const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { +static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, @@ -2284,7 +2284,7 @@ const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 0x1041003c, 0x1041003b, 0x10410039, 0x10410037, }; -const u32 b43_ntab_tx_gain_rev3_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, @@ -2319,7 +2319,7 @@ const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037, }; -const u32 b43_ntab_tx_gain_rev4_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, @@ -2354,7 +2354,7 @@ const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034, }; -const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, @@ -2389,7 +2389,7 @@ const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 0x0062003b, 0x00620039, 0x00620037, 0x00620035, }; -const u32 txpwrctrl_tx_gain_ipa[] = { +static const u32 txpwrctrl_tx_gain_ipa[] = { 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, @@ -2424,7 +2424,7 @@ const u32 txpwrctrl_tx_gain_ipa[] = { 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025, }; -const u32 txpwrctrl_tx_gain_ipa_rev5[] = { +static const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, @@ -2459,7 +2459,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025, }; -const u32 txpwrctrl_tx_gain_ipa_rev6[] = { +static const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, @@ -2494,7 +2494,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025, }; -const u32 txpwrctrl_tx_gain_ipa_5g[] = { +static const u32 txpwrctrl_tx_gain_ipa_5g[] = { 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, @@ -2529,6 +2529,11 @@ const u32 txpwrctrl_tx_gain_ipa_5g[] = { 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f, }; +const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = { + -114, -108, -98, -91, -84, -78, -70, -62, + -54, -46, -39, -31, -23, -15, -8, 0 +}; + const u16 tbl_iqcal_gainparams[2][9][8] = { { { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 }, @@ -2739,11 +2744,11 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ - { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ + { 0x0010, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ - { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ - { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ + { 0x0080, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ + { 0x0100, 8, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ @@ -3126,6 +3131,53 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) B43_WARN_ON(1); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ +static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if (dev->phy.rev >= 6) { + if (dev->dev->chip_id == 47162) + return txpwrctrl_tx_gain_ipa_rev5; + return txpwrctrl_tx_gain_ipa_rev6; + } else if (dev->phy.rev >= 5) { + return txpwrctrl_tx_gain_ipa_rev5; + } else { + return txpwrctrl_tx_gain_ipa; + } + } else { + return txpwrctrl_tx_gain_ipa_5g; + } +} + +const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev) +{ + enum ieee80211_band band = b43_current_band(dev->wl); + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + if (dev->phy.rev < 3) + return b43_ntab_tx_gain_rev0_1_2; + + /* rev 3+ */ + if ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) || + (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) { + return b43_nphy_get_ipa_gain_table(dev); + } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + if (dev->phy.rev == 3) + return b43_ntab_tx_gain_rev3_5ghz; + if (dev->phy.rev == 4) + return sprom->fem.ghz5.extpa_gain == 3 ? + b43_ntab_tx_gain_rev4_5ghz : + b43_ntab_tx_gain_rev4_5ghz; /* FIXME */ + else + return b43_ntab_tx_gain_rev5plus_5ghz; + } else { + if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3) + return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */ + else + return b43_ntab_tx_gain_rev3plus_2ghz; + } +} + struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( struct b43_wldev *dev, bool ghz5, bool ext_lna) { diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 97038c48193..f348953c023 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -177,16 +177,10 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); -extern const u32 b43_ntab_tx_gain_rev0_1_2[]; -extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[]; -extern const u32 b43_ntab_tx_gain_rev3_5ghz[]; -extern const u32 b43_ntab_tx_gain_rev4_5ghz[]; -extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[]; - -extern const u32 txpwrctrl_tx_gain_ipa[]; -extern const u32 txpwrctrl_tx_gain_ipa_rev5[]; -extern const u32 txpwrctrl_tx_gain_ipa_rev6[]; -extern const u32 txpwrctrl_tx_gain_ipa_5g[]; +const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); + +extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[]; + extern const u16 tbl_iqcal_gainparams[2][9][8]; extern const struct nphy_txiqcal_ladder ladder_lo[]; extern const struct nphy_txiqcal_ladder ladder_iq[]; diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 98e3d44400c..a29da674e69 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -581,6 +581,9 @@ struct b43legacy_wl { struct mutex mutex; /* locks wireless core state */ spinlock_t leds_lock; /* lock for leds */ + /* firmware loading work */ + struct work_struct firmware_load; + /* We can only have one operating interface (802.11 core) * at a time. General information about this interface follows. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 75e70bce40f..df7e16dfb36 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1557,8 +1557,15 @@ err_format: return -EPROTO; } -static int b43legacy_request_firmware(struct b43legacy_wldev *dev) +static int b43legacy_one_core_attach(struct ssb_device *dev, + struct b43legacy_wl *wl); +static void b43legacy_one_core_detach(struct ssb_device *dev); + +static void b43legacy_request_firmware(struct work_struct *work) { + struct b43legacy_wl *wl = container_of(work, + struct b43legacy_wl, firmware_load); + struct b43legacy_wldev *dev = wl->current_dev; struct b43legacy_firmware *fw = &dev->fw; const u8 rev = dev->dev->id.revision; const char *filename; @@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) if (err) goto err_load; } + err = ieee80211_register_hw(wl->hw); + if (err) + goto err_one_core_detach; + return; - return 0; +err_one_core_detach: + b43legacy_one_core_detach(dev->dev); + goto error; err_load: b43legacy_print_fw_helptext(dev->wl); @@ -1639,7 +1652,7 @@ err_no_initvals: error: b43legacy_release_firmware(dev); - return err; + return; } static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) @@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) macctl |= B43legacy_MACCTL_INFRA; b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); - err = b43legacy_request_firmware(dev); - if (err) - goto out; err = b43legacy_upload_microcode(dev); if (err) goto out; /* firmware is released later */ @@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev, if (err) goto err_wireless_exit; - if (first) { - err = ieee80211_register_hw(wl->hw); - if (err) - goto err_one_core_detach; - } + /* setup and start work to load firmware */ + INIT_WORK(&wl->firmware_load, b43legacy_request_firmware); + schedule_work(&wl->firmware_load); out: return err; -err_one_core_detach: - b43legacy_one_core_detach(dev); err_wireless_exit: if (first) b43legacy_wireless_exit(dev, wl); @@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev) /* We must cancel any work here before unregistering from ieee80211, * as the ieee80211 unreg will destroy the workqueue. */ cancel_work_sync(&wldev->restart_work); + cancel_work_sync(&wl->firmware_load); B43legacy_WARN_ON(!wl); if (wl->current_dev == wldev) diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 96faaef3661..950334197f4 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -1860,7 +1860,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) * which accounts for the factor of 4 */ #define REG_MAX_PWR 20 max_pwr = min(REG_MAX_PWR * 4 - - dev->dev->bus->sprom.antenna_gain.ghz24.a0 + - dev->dev->bus->sprom.antenna_gain.a0 - 0x6, max_pwr); /* find the desired power in Q5.2 - power_level is in dBm diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index cd6375de2a6..c5104533e24 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig @@ -26,16 +26,25 @@ config BRCMFMAC it'll be called brcmfmac.ko. config BRCMFMAC_SDIO - bool "SDIO bus interface support for FullMAC" + bool "SDIO bus interface support for FullMAC driver" depends on MMC depends on BRCMFMAC select FW_LOADER default y ---help--- This option enables the SDIO bus interface support for Broadcom - FullMAC WLAN driver. - Say Y if you want to use brcmfmac for a compatible SDIO interface - wireless card. + IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to + use the driver for a SDIO wireless card. + +config BRCMFMAC_USB + bool "USB bus interface support for FullMAC driver" + depends on USB + depends on BRCMFMAC + select FW_LOADER + ---help--- + This option enables the USB bus interface support for Broadcom + IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to + use the driver for an USB wireless card. config BRCMDBG bool "Broadcom driver debug functions" diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile index f41c047eca8..b987920e982 100644 --- a/drivers/net/wireless/brcm80211/Makefile +++ b/drivers/net/wireless/brcm80211/Makefile @@ -16,7 +16,7 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # common flags -subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG +subdir-ccflags-$(CONFIG_BRCMDBG) += -DDEBUG obj-$(CONFIG_BRCMUTIL) += brcmutil/ obj-$(CONFIG_BRCMFMAC) += brcmfmac/ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 9ca9ea1135e..abb48032753 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -19,6 +19,8 @@ ccflags-y += \ -Idrivers/net/wireless/brcm80211/brcmfmac \ -Idrivers/net/wireless/brcm80211/include +ccflags-y += -D__CHECK_ENDIAN__ + obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += \ wl_cfg80211.o \ @@ -30,5 +32,5 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ bcmsdh.o \ bcmsdh_sdmmc.o \ sdio_chip.o - -ccflags-y += -D__CHECK_ENDIAN__ +brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ + usb.o diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 4bc8d251acf..e925290b432 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -15,6 +15,8 @@ */ /* ****************** SDIO CARD Interface Functions **************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/netdevice.h> #include <linux/export.h> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 9b8c0ed833d..4688904908e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -13,6 +13,9 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/netdevice.h> #include <linux/mmc/sdio.h> @@ -291,13 +294,14 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt) { int status; - uint pkt_len = pkt->len; + uint pkt_len; bool fifo = (fix_inc == SDIOH_DATA_FIX); brcmf_dbg(TRACE, "Enter\n"); if (pkt == NULL) return -EINVAL; + pkt_len = pkt->len; brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); if (brcmf_pm_resume_error(sdiodev)) @@ -485,7 +489,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, sdiodev->func[0] = func->card->sdio_func[0]; sdiodev->func[1] = func; sdiodev->bus_if = bus_if; - bus_if->bus_priv = sdiodev; + bus_if->bus_priv.sdio = sdiodev; bus_if->type = SDIO_BUS; bus_if->align = BRCMF_SDALIGN; dev_set_drvdata(&func->card->dev, sdiodev); @@ -526,7 +530,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) if (func->num == 2) { bus_if = dev_get_drvdata(&func->dev); - sdiodev = bus_if->bus_priv; + sdiodev = bus_if->bus_priv.sdio; brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); brcmf_sdio_remove(sdiodev); dev_set_drvdata(&func->card->dev, NULL); @@ -593,14 +597,14 @@ static struct sdio_driver brcmf_sdmmc_driver = { #endif /* CONFIG_PM_SLEEP */ }; -static void __exit brcmf_sdio_exit(void) +void brcmf_sdio_exit(void) { brcmf_dbg(TRACE, "Enter\n"); sdio_unregister_driver(&brcmf_sdmmc_driver); } -static int __init brcmf_sdio_init(void) +void brcmf_sdio_init(void) { int ret; @@ -610,9 +614,4 @@ static int __init brcmf_sdio_init(void) if (ret) brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); - - return ret; } - -module_init(brcmf_sdio_init); -module_exit(brcmf_sdio_exit); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index e58ea40a75b..07686a748d3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -644,9 +644,9 @@ extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); -#ifdef BCMDBG +#ifdef DEBUG extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); -#endif /* BCMDBG */ +#endif /* DEBUG */ extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index ad9be2410b5..366916494be 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -39,8 +39,11 @@ struct dngl_stats { /* interface structure between common and bus layer */ struct brcmf_bus { u8 type; /* bus type */ - void *bus_priv; /* pointer to bus private structure */ - void *drvr; /* pointer to driver pub structure brcmf_pub */ + union { + struct brcmf_sdio_dev *sdio; + struct brcmf_usbdev *usb; + } bus_priv; + struct brcmf_pub *drvr; /* pointer to driver pub structure brcmf_pub */ enum brcmf_bus_state state; uint maxctl; /* Max size rxctl request from proto to bus */ bool drvr_up; /* Status flag of driver up/down */ @@ -102,4 +105,14 @@ extern int brcmf_bus_start(struct device *dev); extern int brcmf_add_if(struct device *dev, int ifidx, char *name, u8 *mac_addr); + +#ifdef CONFIG_BRCMFMAC_SDIO +extern void brcmf_sdio_exit(void); +extern void brcmf_sdio_init(void); +#endif +#ifdef CONFIG_BRCMFMAC_USB +extern void brcmf_usb_exit(void); +extern void brcmf_usb_init(void); +#endif + #endif /* _BRCMF_BUS_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index ac8d1f43788..b3e3b7f25d8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -19,6 +19,8 @@ * For certain dcmd codes, the dongle interprets string data from the host. ******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/netdevice.h> #include <linux/sched.h> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index a51d8f5d36f..4187435220f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -13,6 +13,9 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/string.h> #include <linux/sched.h> @@ -38,7 +41,7 @@ #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) -#ifdef BCMDBG +#ifdef DEBUG static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " __DATE__ " at " __TIME__; @@ -133,7 +136,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, return p != NULL; } -#ifdef BCMDBG +#ifdef DEBUG static void brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) { @@ -399,10 +402,10 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) p = (char *)&buf[sizeof(struct msgtrace_hdr)]; while ((s = strstr(p, "\n")) != NULL) { *s = '\0'; - printk(KERN_DEBUG"%s\n", p); + pr_debug("%s\n", p); p = s + 1; } - printk(KERN_DEBUG "%s\n", p); + pr_debug("%s\n", p); /* Reset datalen to avoid display below */ datalen = 0; @@ -430,7 +433,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) brcmf_dbg(EVENT, "\n"); } } -#endif /* BCMDBG */ +#endif /* DEBUG */ int brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, @@ -518,9 +521,9 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, break; } -#ifdef BCMDBG +#ifdef DEBUG brcmf_c_show_host_event(event, event_data); -#endif /* BCMDBG */ +#endif /* DEBUG */ return 0; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index bb26ee36bc6..a2c4576cf9f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -32,20 +32,20 @@ #define BRCMF_BTA_VAL 0x1000 #define BRCMF_ISCAN_VAL 0x2000 -#if defined(BCMDBG) +#if defined(DEBUG) #define brcmf_dbg(level, fmt, ...) \ do { \ if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \ if (brcmf_msg_level & BRCMF_##level##_VAL) { \ if (net_ratelimit()) \ - printk(KERN_DEBUG "%s: " fmt, \ - __func__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } else { \ if (brcmf_msg_level & BRCMF_##level##_VAL) { \ - printk(KERN_DEBUG "%s: " fmt, \ - __func__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) @@ -56,7 +56,7 @@ do { \ #define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) -#else /* (defined BCMDBG) || (defined BCMDBG) */ +#else /* (defined DEBUG) || (defined DEBUG) */ #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__) @@ -66,7 +66,13 @@ do { \ #define BRCMF_BYTES_ON() 0 #define BRCMF_GLOM_ON() 0 -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ + +#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \ +do { \ + if (test) \ + brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__); \ +} while (0) extern int brcmf_msg_level; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index eb9eb766ac2..2a1e5ae0c40 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/init.h> #include <linux/kernel.h> #include <linux/kthread.h> @@ -590,8 +592,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, sprintf(info->bus_info, "%s", dev_name(drvr->dev)); } -static struct ethtool_ops brcmf_ethtool_ops = { - .get_drvinfo = brcmf_ethtool_get_drvinfo +static const struct ethtool_ops brcmf_ethtool_ops = { + .get_drvinfo = brcmf_ethtool_get_drvinfo, }; static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) @@ -794,18 +796,19 @@ static int brcmf_netdev_open(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_bus *bus_if = drvr->bus_if; u32 toe_ol; s32 ret = 0; brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); if (ifp->idx == 0) { /* do it only for primary eth0 */ - /* try to bring up bus */ - ret = brcmf_bus_start(drvr->dev); - if (ret != 0) { - brcmf_dbg(ERROR, "failed with code %d\n", ret); - return -1; + /* If bus is not ready, can't continue */ + if (bus_if->state != BRCMF_BUS_DATA) { + brcmf_dbg(ERROR, "failed bus is not ready\n"); + return -EAGAIN; } + atomic_set(&drvr->pend_8021x_cnt, 0); memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); @@ -977,12 +980,6 @@ int brcmf_bus_start(struct device *dev) return ret; } - /* If bus is not ready, can't come up */ - if (bus_if->state != BRCMF_BUS_DATA) { - brcmf_dbg(ERROR, "failed bus is not ready\n"); - return -ENODEV; - } - brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, iovbuf, @@ -1019,6 +1016,8 @@ int brcmf_bus_start(struct device *dev) if (ret < 0) return ret; + /* signal bus ready */ + bus_if->state = BRCMF_BUS_DATA; return 0; } @@ -1107,13 +1106,13 @@ void brcmf_detach(struct device *dev) if (drvr->iflist[i]) brcmf_del_if(drvr, i); - cancel_work_sync(&drvr->setmacaddr_work); - cancel_work_sync(&drvr->multicast_work); - brcmf_bus_detach(drvr); - if (drvr->prot) + if (drvr->prot) { + cancel_work_sync(&drvr->setmacaddr_work); + cancel_work_sync(&drvr->multicast_work); brcmf_proto_detach(drvr); + } bus_if->drvr = NULL; kfree(drvr); @@ -1146,7 +1145,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) return pend; } -#ifdef BCMDBG +#ifdef DEBUG int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) { int ret = 0; @@ -1180,4 +1179,38 @@ exit: return ret; } -#endif /* BCMDBG */ +#endif /* DEBUG */ + +static void brcmf_driver_init(struct work_struct *work) +{ +#ifdef CONFIG_BRCMFMAC_SDIO + brcmf_sdio_init(); +#endif +#ifdef CONFIG_BRCMFMAC_USB + brcmf_usb_init(); +#endif +} +static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); + +static int __init brcmfmac_module_init(void) +{ + if (!schedule_work(&brcmf_driver_work)) + return -EBUSY; + + return 0; +} + +static void __exit brcmfmac_module_exit(void) +{ + cancel_work_sync(&brcmf_driver_work); + +#ifdef CONFIG_BRCMFMAC_SDIO + brcmf_sdio_exit(); +#endif +#ifdef CONFIG_BRCMFMAC_USB + brcmf_usb_exit(); +#endif +} + +module_init(brcmfmac_module_init); +module_exit(brcmfmac_module_exit); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f7eeee1dcdb..2bf5dda2929 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/kernel.h> #include <linux/kthread.h> @@ -40,7 +42,7 @@ #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ -#ifdef BCMDBG +#ifdef DEBUG #define BRCMF_TRAP_INFO_SIZE 80 @@ -84,7 +86,7 @@ struct rte_console { char cbuf[CBUF_LEN]; }; -#endif /* BCMDBG */ +#endif /* DEBUG */ #include <chipcommon.h> #include "dhd_bus.h" @@ -307,10 +309,10 @@ struct rte_console { /* Flags for SDH calls */ #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) -#define BRCMFMAC_FW_NAME "brcm/brcmfmac.bin" -#define BRCMFMAC_NV_NAME "brcm/brcmfmac.txt" -MODULE_FIRMWARE(BRCMFMAC_FW_NAME); -MODULE_FIRMWARE(BRCMFMAC_NV_NAME); +#define BRCMF_SDIO_FW_NAME "brcm/brcmfmac-sdio.bin" +#define BRCMF_SDIO_NV_NAME "brcm/brcmfmac-sdio.txt" +MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME); +MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME); #define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */ #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change @@ -416,7 +418,7 @@ struct sdpcmd_regs { u16 PAD[0x80]; }; -#ifdef BCMDBG +#ifdef DEBUG /* Device console log buffer state */ struct brcmf_console { uint count; /* Poll interval msec counter */ @@ -426,7 +428,7 @@ struct brcmf_console { u8 *buf; /* Log buffer (host copy) */ uint last; /* Last buffer read index */ }; -#endif /* BCMDBG */ +#endif /* DEBUG */ struct sdpcm_shared { u32 flags; @@ -507,11 +509,11 @@ struct brcmf_sdio { uint polltick; /* Tick counter */ uint pollcnt; /* Count of active polls */ -#ifdef BCMDBG +#ifdef DEBUG uint console_interval; struct brcmf_console console; /* Console output polling support */ uint console_addr; /* Console address from shared struct */ -#endif /* BCMDBG */ +#endif /* DEBUG */ uint regfails; /* Count of R_REG failures */ @@ -587,10 +589,10 @@ struct brcmf_sdio { #define CLK_PENDING 2 /* Not used yet */ #define CLK_AVAIL 3 -#ifdef BCMDBG +#ifdef DEBUG static int qcount[NUMPRIO]; static int tx_packets[NUMPRIO]; -#endif /* BCMDBG */ +#endif /* DEBUG */ #define SDIO_DRIVE_STRENGTH 6 /* in milliamps */ @@ -764,12 +766,12 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) bus->clkstate = CLK_AVAIL; brcmf_dbg(INFO, "CLKCTL: turned ON\n"); -#if defined(BCMDBG) - if (bus->alp_only != true) { +#if defined(DEBUG) + if (!bus->alp_only) { if (SBSDIO_ALPONLY(clkctl)) brcmf_dbg(ERROR, "HT Clock should be on\n"); } -#endif /* defined (BCMDBG) */ +#endif /* defined (DEBUG) */ bus->activity = true; } else { @@ -814,9 +816,9 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) /* Transition SD and backplane clock readiness */ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) { -#ifdef BCMDBG +#ifdef DEBUG uint oldstate = bus->clkstate; -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(TRACE, "Enter\n"); @@ -861,9 +863,9 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) brcmf_sdbrcm_wd_timer(bus, 0); break; } -#ifdef BCMDBG +#ifdef DEBUG brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate); -#endif /* BCMDBG */ +#endif /* DEBUG */ return 0; } @@ -1279,13 +1281,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } return 0; } -#ifdef BCMDBG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "SUPERFRAME:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pfirst->data, min_t(int, pfirst->len, 48)); - } -#endif + + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pfirst->data, min_t(int, pfirst->len, 48), + "SUPERFRAME:\n"); /* Validate the superframe header */ dptr = (u8 *) (pfirst->data); @@ -1362,13 +1361,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef BCMDBG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "subframe:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - dptr, 32); - } -#endif + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + dptr, 32, "subframe:\n"); if ((u16)~(sublen ^ check)) { brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n", @@ -1433,13 +1427,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } rxseq++; -#ifdef BCMDBG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Subframe Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - dptr, dlen); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + dptr, dlen, "Rx Subframe Data:\n"); __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); @@ -1457,17 +1446,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) continue; } -#ifdef BCMDBG - if (BRCMF_GLOM_ON()) { - brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", - bus->glom.qlen, pfirst, pfirst->data, - pfirst->len, pfirst->next, - pfirst->prev); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pfirst->data, - min_t(int, pfirst->len, 32)); - } -#endif /* BCMDBG */ + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pfirst->data, + min_t(int, pfirst->len, 32), + "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", + bus->glom.qlen, pfirst, pfirst->data, + pfirst->len, pfirst->next, + pfirst->prev); } /* sent any remaining packets up */ if (bus->glom.qlen) { @@ -1584,12 +1569,8 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) gotpkt: -#ifdef BCMDBG - if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { - printk(KERN_DEBUG "RxCtrl:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), + bus->rxctl, len, "RxCtrl:\n"); /* Point to valid data and indicate its length */ bus->rxctl += doff; @@ -1818,17 +1799,13 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) } bus->tx_max = txmax; -#ifdef BCMDBG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - rxbuf, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "RxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - bus->rxhdr, SDPCM_HDRLEN); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + rxbuf, len, "Rx Data:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && + BRCMF_DATA_ON()) && + BRCMF_HDRS_ON(), + bus->rxhdr, SDPCM_HDRLEN, + "RxHdr:\n"); if (chan == SDPCM_CONTROL_CHANNEL) { brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n", @@ -1865,13 +1842,9 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_sdbrcm_rxfail(bus, true, true); continue; } -#ifdef BCMDBG - if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "RxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - bus->rxhdr, SDPCM_HDRLEN); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(), + bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n"); + /* Extract hardware header fields */ len = get_unaligned_le16(bus->rxhdr); @@ -2024,13 +1997,8 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) skb_push(pkt, BRCMF_FIRSTREAD); memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD); -#ifdef BCMDBG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pkt->data, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + pkt->data, len, "Rx Data:\n"); deliver: /* Save superframe descriptor and allocate packet frame */ @@ -2038,14 +2006,9 @@ deliver: if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", len); -#ifdef BCMDBG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "Glom Data:\n"); - print_hex_dump_bytes("", - DUMP_PREFIX_OFFSET, - pkt->data, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pkt->data, len, + "Glom Data:\n"); __skb_trim(pkt, len); skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; @@ -2078,13 +2041,11 @@ deliver: down(&bus->sdsem); } rxcount = maxframes - rxleft; -#ifdef BCMDBG /* Message if we hit the limit */ if (!rxleft) brcmf_dbg(DATA, "hit rx limit of %d frames\n", maxframes); else -#endif /* BCMDBG */ brcmf_dbg(DATA, "processed %d frames\n", rxcount); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) @@ -2098,8 +2059,7 @@ static void brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar) { up(&bus->sdsem); - wait_event_interruptible_timeout(bus->ctrl_wait, - (*lockvar == false), HZ * 2); + wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2); down(&bus->sdsem); return; } @@ -2176,20 +2136,22 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); -#ifdef BCMDBG +#ifdef DEBUG tx_packets[pkt->priority]++; - if (BRCMF_BYTES_ON() && - (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - printk(KERN_DEBUG "Tx Frame:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "TxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, min_t(u16, len, 16)); - } #endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)), + frame, len, "Tx Frame:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && + chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && + chan != SDPCM_CONTROL_CHANNEL))) && + BRCMF_HDRS_ON(), + frame, min_t(u16, len, 16), "TxHdr:\n"); + /* Raise len to next SDIO block to eliminate tail command */ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { u16 pad = bus->blocksize - (len % bus->blocksize); @@ -2314,7 +2276,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) uint retries; int err; struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; brcmf_dbg(TRACE, "Enter\n"); @@ -2410,7 +2372,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) int err; u8 clkctl, devctl = 0; -#ifdef BCMDBG +#ifdef DEBUG /* Check for inconsistent device control */ devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); @@ -2418,7 +2380,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, @@ -2664,7 +2626,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) int ret = -EBADE; uint datalen, prec; struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; brcmf_dbg(TRACE, "Enter\n"); @@ -2684,8 +2646,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) /* Priority based enq */ spin_lock_bh(&bus->txqlock); - if (brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec) == - false) { + if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { skb_pull(pkt, SDPCM_HDRLEN); brcmf_txcomplete(bus->sdiodev->dev, pkt, false); brcmu_pkt_buf_free_skb(pkt); @@ -2701,7 +2662,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON); } -#ifdef BCMDBG +#ifdef DEBUG if (pktq_plen(&bus->txq, prec) > qcount[prec]) qcount[prec] = pktq_plen(&bus->txq, prec); #endif @@ -2774,7 +2735,7 @@ xfer_done: return bcmerror; } -#ifdef BCMDBG +#ifdef DEBUG #define CONSOLE_LINE_MAX 192 static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) @@ -2845,14 +2806,14 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) if (line[n - 1] == '\r') n--; line[n] = 0; - printk(KERN_DEBUG "CONSOLE: %s\n", line); + pr_debug("CONSOLE: %s\n", line); } } break2: return 0; } -#endif /* BCMDBG */ +#endif /* DEBUG */ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) { @@ -2906,7 +2867,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) u8 doff = 0; int ret = -1; struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; brcmf_dbg(TRACE, "Enter\n"); @@ -2972,7 +2933,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); - if (bus->ctrl_frame_stat == false) { + if (!bus->ctrl_frame_stat) { brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); ret = 0; } else { @@ -2982,17 +2943,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } if (ret == -1) { -#ifdef BCMDBG - if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { - printk(KERN_DEBUG "Tx Frame:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "TxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, min_t(u16, len, 16)); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), + frame, len, "Tx Frame:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) && + BRCMF_HDRS_ON(), + frame, min_t(u16, len, 16), "TxHdr:\n"); do { ret = brcmf_tx_frame(bus, frame, len); @@ -3021,7 +2976,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) uint rxlen = 0; bool pending; struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; brcmf_dbg(TRACE, "Enter\n"); @@ -3040,7 +2995,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) rxlen, msglen); } else if (timeleft == 0) { brcmf_dbg(ERROR, "resumed on timeout\n"); - } else if (pending == true) { + } else if (pending) { brcmf_dbg(CTL, "cancelled\n"); return -ERESTARTSYS; } else { @@ -3096,9 +3051,9 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) u8 *vbuffer; u32 varsizew; __le32 varsizew_le; -#ifdef BCMDBG +#ifdef DEBUG char *nvram_ularray; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Even if there are no vars are to be written, we still need to set the ramsize. */ @@ -3115,7 +3070,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) /* Write the vars list */ bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); -#ifdef BCMDBG +#ifdef DEBUG /* Verify NVRAM bytes */ brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); nvram_ularray = kmalloc(varsize, GFP_ATOMIC); @@ -3142,7 +3097,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n"); kfree(nvram_ularray); -#endif /* BCMDBG */ +#endif /* DEBUG */ kfree(vbuffer); } @@ -3245,7 +3200,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) brcmf_dbg(INFO, "Enter\n"); - ret = request_firmware(&bus->firmware, BRCMFMAC_FW_NAME, + ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME, &bus->sdiodev->func[2]->dev); if (ret) { brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret); @@ -3342,7 +3297,7 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) char *bufp; int ret; - ret = request_firmware(&bus->firmware, BRCMFMAC_NV_NAME, + ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, &bus->sdiodev->func[2]->dev); if (ret) { brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret); @@ -3432,7 +3387,7 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) static int brcmf_sdbrcm_bus_init(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv; + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; unsigned long timeout; uint retries = 0; @@ -3507,16 +3462,12 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_WATERMARK, 8, &err); - - /* Set bus state according to enable result */ - bus_if->state = BRCMF_BUS_DATA; - } - - else { + } else { /* Disable F2 again */ enable = SDIO_FUNC_ENABLE_1; brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, enable, NULL); + ret = -ENODEV; } /* Restore previous clock setting */ @@ -3524,7 +3475,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); /* If we didn't come up, turn off backplane clock */ - if (bus_if->state != BRCMF_BUS_DATA) + if (!ret) brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); exit: @@ -3569,9 +3520,9 @@ void brcmf_sdbrcm_isr(void *arg) static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) { -#ifdef BCMDBG +#ifdef DEBUG struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(TIMER, "Enter\n"); @@ -3616,7 +3567,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) /* Update interrupt tracking */ bus->lastintrs = bus->intrcount; } -#ifdef BCMDBG +#ifdef DEBUG /* Poll for console output periodically */ if (bus_if->state == BRCMF_BUS_DATA && bus->console_interval != 0) { @@ -3630,7 +3581,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->console_interval = 0; } } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* On idle timeout clear activity flag and/or turn off clock */ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { @@ -3721,11 +3672,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE)) brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); -#ifdef BCMDBG - printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", - brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); - -#endif /* BCMDBG */ + pr_debug("F1 signature read @0x18000000=0x%4x\n", + brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); /* * Force PLL off until brcmf_sdio_chip_attach() @@ -3944,8 +3892,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, bus, "brcmf_watchdog"); if (IS_ERR(bus->watchdog_tsk)) { - printk(KERN_WARNING - "brcmf_watchdog thread failed to start\n"); + pr_warn("brcmf_watchdog thread failed to start\n"); bus->watchdog_tsk = NULL; } /* Initialize DPC thread */ @@ -3953,8 +3900,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, bus, "brcmf_dpc"); if (IS_ERR(bus->dpc_tsk)) { - printk(KERN_WARNING - "brcmf_dpc thread failed to start\n"); + pr_warn("brcmf_dpc thread failed to start\n"); bus->dpc_tsk = NULL; } @@ -4031,7 +3977,7 @@ void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick) { /* Totally stop the timer */ - if (!wdtick && bus->wd_timer_valid == true) { + if (!wdtick && bus->wd_timer_valid) { del_timer_sync(&bus->timer); bus->wd_timer_valid = false; bus->save_ms = wdtick; @@ -4044,7 +3990,7 @@ brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick) if (wdtick) { if (bus->save_ms != BRCMF_WD_POLL_MS) { - if (bus->wd_timer_valid == true) + if (bus->wd_timer_valid) /* Stop timer and restart at new value */ del_timer_sync(&bus->timer); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 11b2d7c97ba..1534efc2163 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -15,6 +15,8 @@ */ /* ***** SDIO interface chip backplane handle functions ***** */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/types.h> #include <linux/netdevice.h> #include <linux/mmc/card.h> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c new file mode 100644 index 00000000000..82364223e81 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -0,0 +1,1621 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/kthread.h> +#include <linux/slab.h> +#include <linux/skbuff.h> +#include <linux/netdevice.h> +#include <linux/spinlock.h> +#include <linux/ethtool.h> +#include <linux/fcntl.h> +#include <linux/fs.h> +#include <linux/uaccess.h> +#include <linux/firmware.h> +#include <linux/usb.h> +#include <net/cfg80211.h> + +#include <defs.h> +#include <brcmu_utils.h> +#include <brcmu_wifi.h> +#include <dhd_bus.h> +#include <dhd_dbg.h> + +#include "usb_rdl.h" +#include "usb.h" + +#define IOCTL_RESP_TIMEOUT 2000 + +#define BRCMF_USB_SYNC_TIMEOUT 300 /* ms */ +#define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ +#define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ + +#define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle + has boot up */ +#define BRCMF_USB_RESETCFG_SPINWAIT 1 /* wait after resetcfg (ms) */ + +#define BRCMF_USB_NRXQ 50 +#define BRCMF_USB_NTXQ 50 + +#define CONFIGDESC(usb) (&((usb)->actconfig)->desc) +#define IFPTR(usb, idx) ((usb)->actconfig->interface[(idx)]) +#define IFALTS(usb, idx) (IFPTR((usb), (idx))->altsetting[0]) +#define IFDESC(usb, idx) IFALTS((usb), (idx)).desc +#define IFEPDESC(usb, idx, ep) (IFALTS((usb), (idx)).endpoint[(ep)]).desc + +#define CONTROL_IF 0 +#define BULK_IF 0 + +#define BRCMF_USB_CBCTL_WRITE 0 +#define BRCMF_USB_CBCTL_READ 1 +#define BRCMF_USB_MAX_PKT_SIZE 1600 + +#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" + +enum usbdev_suspend_state { + USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow + suspend */ + USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be + * suspended. Wating PM to + * suspend the device + */ + USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ +}; + +struct brcmf_usb_probe_info { + void *usbdev_info; + struct usb_device *usb; /* USB device pointer from OS */ + uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; + int intr_size; /* Size of interrupt message */ + int interval; /* Interrupt polling interval */ + int vid; + int pid; + enum usb_device_speed device_speed; + enum usbdev_suspend_state suspend_state; + struct usb_interface *intf; +}; +static struct brcmf_usb_probe_info usbdev_probe_info; + +struct brcmf_usb_image { + void *data; + u32 len; +}; +static struct brcmf_usb_image g_image = { NULL, 0 }; + +struct intr_transfer_buf { + u32 notification; + u32 reserved; +}; + +struct brcmf_usbdev_info { + struct brcmf_usbdev bus_pub; /* MUST BE FIRST */ + spinlock_t qlock; + struct list_head rx_freeq; + struct list_head rx_postq; + struct list_head tx_freeq; + struct list_head tx_postq; + enum usbdev_suspend_state suspend_state; + uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; + + bool activity; + int rx_low_watermark; + int tx_low_watermark; + int tx_high_watermark; + bool txoff; + bool rxoff; + bool txoverride; + + struct brcmf_usbreq *tx_reqs; + struct brcmf_usbreq *rx_reqs; + + u8 *image; /* buffer for combine fw and nvram */ + int image_len; + + wait_queue_head_t wait; + bool waitdone; + int sync_urb_status; + + struct usb_device *usbdev; + struct device *dev; + enum usb_device_speed device_speed; + + int ctl_in_pipe, ctl_out_pipe; + struct urb *ctl_urb; /* URB for control endpoint */ + struct usb_ctrlrequest ctl_write; + struct usb_ctrlrequest ctl_read; + u32 ctl_urb_actual_length; + int ctl_urb_status; + int ctl_completed; + wait_queue_head_t ioctl_resp_wait; + wait_queue_head_t ctrl_wait; + ulong ctl_op; + + bool rxctl_deferrespok; + + struct urb *bulk_urb; /* used for FW download */ + struct urb *intr_urb; /* URB for interrupt endpoint */ + int intr_size; /* Size of interrupt message */ + int interval; /* Interrupt polling interval */ + struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */ + + struct brcmf_usb_probe_info probe_info; + +}; + +static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, + struct brcmf_usbreq *req); + +MODULE_AUTHOR("Broadcom Corporation"); +MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac usb driver."); +MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac usb cards"); +MODULE_LICENSE("Dual BSD/GPL"); + +static struct brcmf_usbdev *brcmf_usb_get_buspub(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + return bus_if->bus_priv.usb; +} + +static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev) +{ + return brcmf_usb_get_buspub(dev)->devinfo; +} + +#if 0 +static void +brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff) +{ + dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff); +} +#endif + +static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo, + uint *condition, bool *pending) +{ + DECLARE_WAITQUEUE(wait, current); + int timeout = IOCTL_RESP_TIMEOUT; + + /* Convert timeout in millsecond to jiffies */ + timeout = msecs_to_jiffies(timeout); + /* Wait until control frame is available */ + add_wait_queue(&devinfo->ioctl_resp_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + smp_mb(); + while (!(*condition) && (!signal_pending(current) && timeout)) { + timeout = schedule_timeout(timeout); + /* Wait until control frame is available */ + smp_mb(); + } + + if (signal_pending(current)) + *pending = true; + + set_current_state(TASK_RUNNING); + remove_wait_queue(&devinfo->ioctl_resp_wait, &wait); + + return timeout; +} + +static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) +{ + if (waitqueue_active(&devinfo->ioctl_resp_wait)) + wake_up_interruptible(&devinfo->ioctl_resp_wait); + + return 0; +} + +static void +brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) +{ + + if (unlikely(devinfo == NULL)) + return; + + if (type == BRCMF_USB_CBCTL_READ) { + if (status == 0) + devinfo->bus_pub.stats.rx_ctlpkts++; + else + devinfo->bus_pub.stats.rx_ctlerrs++; + } else if (type == BRCMF_USB_CBCTL_WRITE) { + if (status == 0) + devinfo->bus_pub.stats.tx_ctlpkts++; + else + devinfo->bus_pub.stats.tx_ctlerrs++; + } + + devinfo->ctl_urb_status = status; + devinfo->ctl_completed = true; + brcmf_usb_ioctl_resp_wake(devinfo); +} + +static void +brcmf_usb_ctlread_complete(struct urb *urb) +{ + struct brcmf_usbdev_info *devinfo = + (struct brcmf_usbdev_info *)urb->context; + + devinfo->ctl_urb_actual_length = urb->actual_length; + brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, + urb->status); +} + +static void +brcmf_usb_ctlwrite_complete(struct urb *urb) +{ + struct brcmf_usbdev_info *devinfo = + (struct brcmf_usbdev_info *)urb->context; + + brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, + urb->status); +} + +static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state) +{ + return 0; +} + +static int +brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) +{ + int ret; + u16 size; + + if (devinfo == NULL || buf == NULL || + len == 0 || devinfo->ctl_urb == NULL) + return -EINVAL; + + /* If the USB/HSIC bus in sleep state, wake it up */ + if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) + if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { + brcmf_dbg(ERROR, "Could not Resume the bus!\n"); + return -EIO; + } + + devinfo->activity = true; + size = len; + devinfo->ctl_write.wLength = cpu_to_le16p(&size); + devinfo->ctl_urb->transfer_buffer_length = size; + devinfo->ctl_urb_status = 0; + devinfo->ctl_urb_actual_length = 0; + + usb_fill_control_urb(devinfo->ctl_urb, + devinfo->usbdev, + devinfo->ctl_out_pipe, + (unsigned char *) &devinfo->ctl_write, + buf, size, + (usb_complete_t)brcmf_usb_ctlwrite_complete, + devinfo); + + ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); + if (ret < 0) + brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); + + return ret; +} + +static int +brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) +{ + int ret; + u16 size; + + if ((devinfo == NULL) || (buf == NULL) || (len == 0) + || (devinfo->ctl_urb == NULL)) + return -EINVAL; + + size = len; + devinfo->ctl_read.wLength = cpu_to_le16p(&size); + devinfo->ctl_urb->transfer_buffer_length = size; + + if (devinfo->rxctl_deferrespok) { + /* BMAC model */ + devinfo->ctl_read.bRequestType = USB_DIR_IN + | USB_TYPE_VENDOR | USB_RECIP_INTERFACE; + devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK; + } else { + /* full dongle model */ + devinfo->ctl_read.bRequestType = USB_DIR_IN + | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + devinfo->ctl_read.bRequest = 1; + } + + usb_fill_control_urb(devinfo->ctl_urb, + devinfo->usbdev, + devinfo->ctl_in_pipe, + (unsigned char *) &devinfo->ctl_read, + buf, size, + (usb_complete_t)brcmf_usb_ctlread_complete, + devinfo); + + ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); + if (ret < 0) + brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); + + return ret; +} + +static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) +{ + int err = 0; + int timeout = 0; + bool pending; + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ + return -EIO; + } + + if (test_and_set_bit(0, &devinfo->ctl_op)) + return -EIO; + + err = brcmf_usb_send_ctl(devinfo, buf, len); + if (err) { + brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); + return err; + } + + devinfo->ctl_completed = false; + timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed, + &pending); + clear_bit(0, &devinfo->ctl_op); + if (!timeout) { + brcmf_dbg(ERROR, "Txctl wait timed out\n"); + err = -EIO; + } + return err; +} + +static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) +{ + int err = 0; + int timeout = 0; + bool pending; + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ + return -EIO; + } + if (test_and_set_bit(0, &devinfo->ctl_op)) + return -EIO; + + err = brcmf_usb_recv_ctl(devinfo, buf, len); + if (err) { + brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); + return err; + } + devinfo->ctl_completed = false; + timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed, + &pending); + err = devinfo->ctl_urb_status; + clear_bit(0, &devinfo->ctl_op); + if (!timeout) { + brcmf_dbg(ERROR, "rxctl wait timed out\n"); + err = -EIO; + } + if (!err) + return devinfo->ctl_urb_actual_length; + else + return err; +} + +static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo, + struct list_head *q) +{ + unsigned long flags; + struct brcmf_usbreq *req; + spin_lock_irqsave(&devinfo->qlock, flags); + if (list_empty(q)) { + spin_unlock_irqrestore(&devinfo->qlock, flags); + return NULL; + } + req = list_entry(q->next, struct brcmf_usbreq, list); + list_del_init(q->next); + spin_unlock_irqrestore(&devinfo->qlock, flags); + return req; + +} + +static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo, + struct list_head *q, struct brcmf_usbreq *req) +{ + unsigned long flags; + spin_lock_irqsave(&devinfo->qlock, flags); + list_add_tail(&req->list, q); + spin_unlock_irqrestore(&devinfo->qlock, flags); +} + +static struct brcmf_usbreq * +brcmf_usbdev_qinit(struct list_head *q, int qsize) +{ + int i; + struct brcmf_usbreq *req, *reqs; + + reqs = kzalloc(sizeof(struct brcmf_usbreq) * qsize, GFP_ATOMIC); + if (reqs == NULL) { + brcmf_dbg(ERROR, "fail to allocate memory!\n"); + return NULL; + } + req = reqs; + + for (i = 0; i < qsize; i++) { + req->urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!req->urb) + goto fail; + + INIT_LIST_HEAD(&req->list); + list_add_tail(&req->list, q); + req++; + } + return reqs; +fail: + brcmf_dbg(ERROR, "fail!\n"); + while (!list_empty(q)) { + req = list_entry(q->next, struct brcmf_usbreq, list); + if (req && req->urb) + usb_free_urb(req->urb); + list_del(q->next); + } + return NULL; + +} + +static void brcmf_usb_free_q(struct list_head *q, bool pending) +{ + struct brcmf_usbreq *req, *next; + int i = 0; + list_for_each_entry_safe(req, next, q, list) { + if (!req->urb) { + brcmf_dbg(ERROR, "bad req\n"); + break; + } + i++; + if (pending) { + usb_kill_urb(req->urb); + } else { + usb_free_urb(req->urb); + list_del_init(&req->list); + } + } +} + +static void brcmf_usb_del_fromq(struct brcmf_usbdev_info *devinfo, + struct brcmf_usbreq *req) +{ + unsigned long flags; + + spin_lock_irqsave(&devinfo->qlock, flags); + list_del_init(&req->list); + spin_unlock_irqrestore(&devinfo->qlock, flags); +} + + +static void brcmf_usb_tx_complete(struct urb *urb) +{ + struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; + struct brcmf_usbdev_info *devinfo = req->devinfo; + + brcmf_usb_del_fromq(devinfo, req); + if (urb->status == 0) + devinfo->bus_pub.bus->dstats.tx_packets++; + else + devinfo->bus_pub.bus->dstats.tx_errors++; + + dev_kfree_skb(req->skb); + req->skb = NULL; + brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); + +} + +static void brcmf_usb_rx_complete(struct urb *urb) +{ + struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; + struct brcmf_usbdev_info *devinfo = req->devinfo; + struct sk_buff *skb; + int ifidx = 0; + + brcmf_usb_del_fromq(devinfo, req); + skb = req->skb; + req->skb = NULL; + + if (urb->status == 0) { + devinfo->bus_pub.bus->dstats.rx_packets++; + } else { + devinfo->bus_pub.bus->dstats.rx_errors++; + dev_kfree_skb(skb); + brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); + return; + } + + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) { + skb_put(skb, urb->actual_length); + if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { + brcmf_dbg(ERROR, "rx protocol error\n"); + brcmu_pkt_buf_free_skb(skb); + devinfo->bus_pub.bus->dstats.rx_errors++; + } else { + brcmf_rx_packet(devinfo->dev, ifidx, skb); + brcmf_usb_rx_refill(devinfo, req); + } + } else { + dev_kfree_skb(skb); + } + return; + +} + +static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, + struct brcmf_usbreq *req) +{ + struct sk_buff *skb; + int ret; + + if (!req || !devinfo) + return; + + skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu); + if (!skb) { + brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); + return; + } + req->skb = skb; + + usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, + skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, + req); + req->urb->transfer_flags |= URB_ZERO_PACKET; + req->devinfo = devinfo; + + ret = usb_submit_urb(req->urb, GFP_ATOMIC); + if (ret == 0) { + brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); + } else { + dev_kfree_skb(req->skb); + req->skb = NULL; + brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); + } + return; +} + +static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo) +{ + struct brcmf_usbreq *req; + + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + brcmf_dbg(ERROR, "bus is not up\n"); + return; + } + while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL) + brcmf_usb_rx_refill(devinfo, req); +} + +static void +brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) +{ + struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; + int old_state; + + + if (devinfo->bus_pub.state == state) + return; + + old_state = devinfo->bus_pub.state; + brcmf_dbg(TRACE, "dbus state change from %d to to %d\n", + old_state, state); + + /* Don't update state if it's PnP firmware re-download */ + if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */ + devinfo->bus_pub.state = state; + + if ((old_state == BCMFMAC_USB_STATE_SLEEP) + && (state == BCMFMAC_USB_STATE_UP)) { + brcmf_usb_rx_fill_all(devinfo); + } + + /* update state of upper layer */ + if (state == BCMFMAC_USB_STATE_DOWN) { + brcmf_dbg(INFO, "DBUS is down\n"); + bcmf_bus->state = BRCMF_BUS_DOWN; + } else { + brcmf_dbg(INFO, "DBUS current state=%d\n", state); + } +} + +static void +brcmf_usb_intr_complete(struct urb *urb) +{ + struct brcmf_usbdev_info *devinfo = + (struct brcmf_usbdev_info *)urb->context; + bool killed; + + if (devinfo == NULL) + return; + + if (unlikely(urb->status)) { + if (devinfo->suspend_state == + USBOS_SUSPEND_STATE_SUSPEND_PENDING) + killed = true; + + if ((urb->status == -ENOENT && (!killed)) + || urb->status == -ESHUTDOWN || + urb->status == -ENODEV) { + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); + } + } + + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) { + brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); + return; + } + + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) + usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); +} + +static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) +{ + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + struct brcmf_usbreq *req; + int ret; + + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ + return -EIO; + } + + req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); + if (!req) { + brcmf_dbg(ERROR, "no req to send\n"); + return -ENOMEM; + } + if (!req->urb) { + brcmf_dbg(ERROR, "no urb for req %p\n", req); + return -ENOBUFS; + } + + req->skb = skb; + req->devinfo = devinfo; + usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, + skb->data, skb->len, brcmf_usb_tx_complete, req); + req->urb->transfer_flags |= URB_ZERO_PACKET; + ret = usb_submit_urb(req->urb, GFP_ATOMIC); + if (!ret) { + brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); + } else { + req->skb = NULL; + brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); + } + + return ret; +} + + +static int brcmf_usb_up(struct device *dev) +{ + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + u16 ifnum; + + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) + return 0; + + /* If the USB/HSIC bus in sleep state, wake it up */ + if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) { + if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { + brcmf_dbg(ERROR, "Could not Resume the bus!\n"); + return -EIO; + } + } + devinfo->activity = true; + + /* Success, indicate devinfo is fully up */ + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); + + if (devinfo->intr_urb) { + int ret; + + usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, + devinfo->intr_pipe, + &devinfo->intr, + devinfo->intr_size, + (usb_complete_t)brcmf_usb_intr_complete, + devinfo, + devinfo->interval); + + ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); + if (ret) { + brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n", + ret); + return -EINVAL; + } + } + + if (devinfo->ctl_urb) { + devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0); + devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0); + + ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber; + + /* CTL Write */ + devinfo->ctl_write.bRequestType = + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + devinfo->ctl_write.bRequest = 0; + devinfo->ctl_write.wValue = cpu_to_le16(0); + devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum); + + /* CTL Read */ + devinfo->ctl_read.bRequestType = + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; + devinfo->ctl_read.bRequest = 1; + devinfo->ctl_read.wValue = cpu_to_le16(0); + devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum); + } + brcmf_usb_rx_fill_all(devinfo); + return 0; +} + +static void brcmf_usb_down(struct device *dev) +{ + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); + + if (devinfo == NULL) + return; + + brcmf_dbg(TRACE, "enter\n"); + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) + return; + + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); + if (devinfo->intr_urb) + usb_kill_urb(devinfo->intr_urb); + + if (devinfo->ctl_urb) + usb_kill_urb(devinfo->ctl_urb); + + if (devinfo->bulk_urb) + usb_kill_urb(devinfo->bulk_urb); + brcmf_usb_free_q(&devinfo->tx_postq, true); + + brcmf_usb_free_q(&devinfo->rx_postq, true); +} + +static int +brcmf_usb_sync_wait(struct brcmf_usbdev_info *devinfo, u16 time) +{ + int ret; + int err = 0; + int ms = time; + + ret = wait_event_interruptible_timeout(devinfo->wait, + devinfo->waitdone == true, (ms * HZ / 1000)); + + if ((devinfo->waitdone == false) || (devinfo->sync_urb_status)) { + brcmf_dbg(ERROR, "timeout(%d) or urb err=%d\n", + ret, devinfo->sync_urb_status); + err = -EINVAL; + } + devinfo->waitdone = false; + return err; +} + +static void +brcmf_usb_sync_complete(struct urb *urb) +{ + struct brcmf_usbdev_info *devinfo = + (struct brcmf_usbdev_info *)urb->context; + + devinfo->waitdone = true; + wake_up_interruptible(&devinfo->wait); + devinfo->sync_urb_status = urb->status; +} + +static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, + void *buffer, int buflen) +{ + int ret = 0; + char *tmpbuf; + u16 size; + + if ((!devinfo) || (devinfo->ctl_urb == NULL)) + return false; + + tmpbuf = kmalloc(buflen, GFP_ATOMIC); + if (!tmpbuf) + return false; + + size = buflen; + devinfo->ctl_urb->transfer_buffer_length = size; + + devinfo->ctl_read.wLength = cpu_to_le16p(&size); + devinfo->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_INTERFACE; + devinfo->ctl_read.bRequest = cmd; + + usb_fill_control_urb(devinfo->ctl_urb, + devinfo->usbdev, + usb_rcvctrlpipe(devinfo->usbdev, 0), + (unsigned char *) &devinfo->ctl_read, + (void *) tmpbuf, size, + (usb_complete_t)brcmf_usb_sync_complete, devinfo); + + ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); + if (ret < 0) { + brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); + kfree(tmpbuf); + return false; + } + + ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); + memcpy(buffer, tmpbuf, buflen); + kfree(tmpbuf); + + return (ret == 0); +} + +static bool +brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) +{ + struct bootrom_id_le id; + u32 chipid, chiprev; + + brcmf_dbg(TRACE, "enter\n"); + + if (devinfo == NULL) + return false; + + /* Check if firmware downloaded already by querying runtime ID */ + id.chip = cpu_to_le32(0xDEAD); + brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, + sizeof(struct bootrom_id_le)); + + chipid = le32_to_cpu(id.chip); + chiprev = le32_to_cpu(id.chiprev); + + if ((chipid & 0x4300) == 0x4300) + brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev); + else + brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev); + if (chipid == BRCMF_POSTBOOT_ID) { + brcmf_dbg(INFO, "firmware already downloaded\n"); + brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, + sizeof(struct bootrom_id_le)); + return false; + } else { + devinfo->bus_pub.devid = chipid; + devinfo->bus_pub.chiprev = chiprev; + } + return true; +} + +static int +brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) +{ + struct bootrom_id_le id; + u16 wait = 0, wait_time; + + brcmf_dbg(TRACE, "enter\n"); + + if (devinfo == NULL) + return -EINVAL; + + /* Give dongle chance to boot */ + wait_time = BRCMF_USB_DLIMAGE_SPINWAIT; + while (wait < BRCMF_USB_DLIMAGE_LIMIT) { + mdelay(wait_time); + wait += wait_time; + id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ + brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, + sizeof(struct bootrom_id_le)); + if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) + break; + } + + if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { + brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n", + wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); + + brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, + sizeof(struct bootrom_id_le)); + + /* XXX this wait may not be necessary */ + mdelay(BRCMF_USB_RESETCFG_SPINWAIT); + return 0; + } else { + brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", + wait); + return -EINVAL; + } +} + + +static int +brcmf_usb_dl_send_bulk(struct brcmf_usbdev_info *devinfo, void *buffer, int len) +{ + int ret; + + if ((devinfo == NULL) || (devinfo->bulk_urb == NULL)) + return -EINVAL; + + /* Prepare the URB */ + usb_fill_bulk_urb(devinfo->bulk_urb, devinfo->usbdev, + devinfo->tx_pipe, buffer, len, + (usb_complete_t)brcmf_usb_sync_complete, devinfo); + + devinfo->bulk_urb->transfer_flags |= URB_ZERO_PACKET; + + ret = usb_submit_urb(devinfo->bulk_urb, GFP_ATOMIC); + if (ret) { + brcmf_dbg(ERROR, "usb_submit_urb failed %d\n", ret); + return ret; + } + ret = brcmf_usb_sync_wait(devinfo, BRCMF_USB_SYNC_TIMEOUT); + return ret; +} + +static int +brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) +{ + unsigned int sendlen, sent, dllen; + char *bulkchunk = NULL, *dlpos; + struct rdl_state_le state; + u32 rdlstate, rdlbytes; + int err = 0; + brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen); + + bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); + if (bulkchunk == NULL) { + err = -ENOMEM; + goto fail; + } + + /* 1) Prepare USB boot loader for runtime image */ + brcmf_usb_dl_cmd(devinfo, DL_START, &state, + sizeof(struct rdl_state_le)); + + rdlstate = le32_to_cpu(state.state); + rdlbytes = le32_to_cpu(state.bytes); + + /* 2) Check we are in the Waiting state */ + if (rdlstate != DL_WAITING) { + brcmf_dbg(ERROR, "Failed to DL_START\n"); + err = -EINVAL; + goto fail; + } + sent = 0; + dlpos = fw; + dllen = fwlen; + + /* Get chip id and rev */ + while (rdlbytes != dllen) { + /* Wait until the usb device reports it received all + * the bytes we sent */ + if ((rdlbytes == sent) && (rdlbytes != dllen)) { + if ((dllen-sent) < RDL_CHUNK) + sendlen = dllen-sent; + else + sendlen = RDL_CHUNK; + + /* simply avoid having to send a ZLP by ensuring we + * never have an even + * multiple of 64 + */ + if (!(sendlen % 64)) + sendlen -= 4; + + /* send data */ + memcpy(bulkchunk, dlpos, sendlen); + if (brcmf_usb_dl_send_bulk(devinfo, bulkchunk, + sendlen)) { + brcmf_dbg(ERROR, "send_bulk failed\n"); + err = -EINVAL; + goto fail; + } + + dlpos += sendlen; + sent += sendlen; + } + if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, + sizeof(struct rdl_state_le))) { + brcmf_dbg(ERROR, "DL_GETSTATE Failed xxxx\n"); + err = -EINVAL; + goto fail; + } + + rdlstate = le32_to_cpu(state.state); + rdlbytes = le32_to_cpu(state.bytes); + + /* restart if an error is reported */ + if (rdlstate == DL_BAD_HDR || rdlstate == DL_BAD_CRC) { + brcmf_dbg(ERROR, "Bad Hdr or Bad CRC state %d\n", + rdlstate); + err = -EINVAL; + goto fail; + } + } + +fail: + kfree(bulkchunk); + brcmf_dbg(TRACE, "err=%d\n", err); + return err; +} + +static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) +{ + int err; + + brcmf_dbg(TRACE, "enter\n"); + + if (devinfo == NULL) + return -EINVAL; + + if (devinfo->bus_pub.devid == 0xDEAD) + return -EINVAL; + + err = brcmf_usb_dl_writeimage(devinfo, fw, len); + if (err == 0) + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE; + else + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING; + brcmf_dbg(TRACE, "exit: err=%d\n", err); + + return err; +} + +static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) +{ + struct rdl_state_le state; + + brcmf_dbg(TRACE, "enter\n"); + if (!devinfo) + return -EINVAL; + + if (devinfo->bus_pub.devid == 0xDEAD) + return -EINVAL; + + /* Check we are runnable */ + brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, + sizeof(struct rdl_state_le)); + + /* Start the image */ + if (state.state == cpu_to_le32(DL_RUNNABLE)) { + if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state, + sizeof(struct rdl_state_le))) + return -ENODEV; + if (brcmf_usb_resetcfg(devinfo)) + return -ENODEV; + /* The Dongle may go for re-enumeration. */ + } else { + brcmf_dbg(ERROR, "Dongle not runnable\n"); + return -EINVAL; + } + brcmf_dbg(TRACE, "exit\n"); + return 0; +} + +static bool brcmf_usb_chip_support(int chipid, int chiprev) +{ + switch(chipid) { + case 43235: + case 43236: + case 43238: + return (chiprev == 3); + default: + break; + } + return false; +} + +static int +brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) +{ + int devid, chiprev; + int err; + + brcmf_dbg(TRACE, "enter\n"); + if (devinfo == NULL) + return -ENODEV; + + devid = devinfo->bus_pub.devid; + chiprev = devinfo->bus_pub.chiprev; + + if (!brcmf_usb_chip_support(devid, chiprev)) { + brcmf_dbg(ERROR, "unsupported chip %d rev %d\n", + devid, chiprev); + return -EINVAL; + } + + if (!devinfo->image) { + brcmf_dbg(ERROR, "No firmware!\n"); + return -ENOENT; + } + + err = brcmf_usb_dlstart(devinfo, + devinfo->image, devinfo->image_len); + if (err == 0) + err = brcmf_usb_dlrun(devinfo); + return err; +} + + +static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub) +{ + struct brcmf_usbdev_info *devinfo = + (struct brcmf_usbdev_info *)bus_pub; + + brcmf_dbg(TRACE, "devinfo %p\n", devinfo); + + /* store the image globally */ + g_image.data = devinfo->image; + g_image.len = devinfo->image_len; + + /* free the URBS */ + brcmf_usb_free_q(&devinfo->rx_freeq, false); + brcmf_usb_free_q(&devinfo->tx_freeq, false); + + usb_free_urb(devinfo->intr_urb); + usb_free_urb(devinfo->ctl_urb); + usb_free_urb(devinfo->bulk_urb); + + kfree(devinfo->tx_reqs); + kfree(devinfo->rx_reqs); + kfree(devinfo); +} + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 /* Version 1 */ +#define TRX_MAX_LEN 0x3B0000 /* Max length */ +#define TRX_NO_HEADER 1 /* Do not write TRX header */ +#define TRX_MAX_OFFSET 3 /* Max number of individual files */ +#define TRX_UNCOMP_IMAGE 0x20 /* Trx contains uncompressed image */ + +struct trx_header_le { + __le32 magic; /* "HDR0" */ + __le32 len; /* Length of file including header */ + __le32 crc32; /* CRC from flag_version to end of file */ + __le32 flag_version; /* 0:15 flags, 16:31 version */ + __le32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of + * header */ +}; + +static int check_file(const u8 *headers) +{ + struct trx_header_le *trx; + int actual_len = -1; + + /* Extract trx header */ + trx = (struct trx_header_le *) headers; + if (trx->magic != cpu_to_le32(TRX_MAGIC)) + return -1; + + headers += sizeof(struct trx_header_le); + + if (le32_to_cpu(trx->flag_version) & TRX_UNCOMP_IMAGE) { + actual_len = le32_to_cpu(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]); + return actual_len + sizeof(struct trx_header_le); + } + return -1; +} + +static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) +{ + s8 *fwname; + const struct firmware *fw; + int err; + + devinfo->image = g_image.data; + devinfo->image_len = g_image.len; + + /* + * if we have an image we can leave here. + */ + if (devinfo->image) + return 0; + + fwname = BRCMF_USB_43236_FW_NAME; + + err = request_firmware(&fw, fwname, devinfo->dev); + if (!fw) { + brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname); + return err; + } + if (check_file(fw->data) < 0) { + brcmf_dbg(ERROR, "invalid firmware %s\n", fwname); + return -EINVAL; + } + + devinfo->image = kmalloc(fw->size, GFP_ATOMIC); /* plus nvram */ + if (!devinfo->image) + return -ENOMEM; + + memcpy(devinfo->image, fw->data, fw->size); + devinfo->image_len = fw->size; + + release_firmware(fw); + return 0; +} + + +static +struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev) +{ + struct brcmf_usbdev_info *devinfo; + + devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC); + if (devinfo == NULL) + return NULL; + + devinfo->bus_pub.nrxq = nrxq; + devinfo->rx_low_watermark = nrxq / 2; + devinfo->bus_pub.devinfo = devinfo; + devinfo->bus_pub.ntxq = ntxq; + + /* flow control when too many tx urbs posted */ + devinfo->tx_low_watermark = ntxq / 4; + devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3; + devinfo->dev = dev; + devinfo->usbdev = usbdev_probe_info.usb; + devinfo->tx_pipe = usbdev_probe_info.tx_pipe; + devinfo->rx_pipe = usbdev_probe_info.rx_pipe; + devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2; + devinfo->intr_pipe = usbdev_probe_info.intr_pipe; + + devinfo->interval = usbdev_probe_info.interval; + devinfo->intr_size = usbdev_probe_info.intr_size; + + memcpy(&devinfo->probe_info, &usbdev_probe_info, + sizeof(struct brcmf_usb_probe_info)); + devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE; + + /* Initialize other structure content */ + init_waitqueue_head(&devinfo->ioctl_resp_wait); + + /* Initialize the spinlocks */ + spin_lock_init(&devinfo->qlock); + + INIT_LIST_HEAD(&devinfo->rx_freeq); + INIT_LIST_HEAD(&devinfo->rx_postq); + + INIT_LIST_HEAD(&devinfo->tx_freeq); + INIT_LIST_HEAD(&devinfo->tx_postq); + + devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq); + if (!devinfo->rx_reqs) + goto error; + + devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq); + if (!devinfo->tx_reqs) + goto error; + + devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!devinfo->intr_urb) { + brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n"); + goto error; + } + devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!devinfo->ctl_urb) { + brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n"); + goto error; + } + devinfo->rxctl_deferrespok = 0; + + devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!devinfo->bulk_urb) { + brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n"); + goto error; + } + + init_waitqueue_head(&devinfo->wait); + if (!brcmf_usb_dlneeded(devinfo)) + return &devinfo->bus_pub; + + brcmf_dbg(TRACE, "start fw downloading\n"); + if (brcmf_usb_get_fw(devinfo)) + goto error; + + if (brcmf_usb_fw_download(devinfo)) + goto error; + + return &devinfo->bus_pub; + +error: + brcmf_dbg(ERROR, "failed!\n"); + brcmf_usb_detach(&devinfo->bus_pub); + return NULL; +} + +static int brcmf_usb_probe_cb(struct device *dev, const char *desc, + u32 bustype, u32 hdrlen) +{ + struct brcmf_bus *bus = NULL; + struct brcmf_usbdev *bus_pub = NULL; + int ret; + + + bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev); + if (!bus_pub) { + ret = -ENODEV; + goto fail; + } + + bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); + if (!bus) { + ret = -ENOMEM; + goto fail; + } + + bus_pub->bus = bus; + bus->brcmf_bus_txdata = brcmf_usb_tx; + bus->brcmf_bus_init = brcmf_usb_up; + bus->brcmf_bus_stop = brcmf_usb_down; + bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; + bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; + bus->type = bustype; + bus->bus_priv.usb = bus_pub; + dev_set_drvdata(dev, bus); + + /* Attach to the common driver interface */ + ret = brcmf_attach(hdrlen, dev); + if (ret) { + brcmf_dbg(ERROR, "dhd_attach failed\n"); + goto fail; + } + + ret = brcmf_bus_start(dev); + if (ret == -ENOLINK) { + brcmf_dbg(ERROR, "dongle is not responding\n"); + brcmf_detach(dev); + goto fail; + } + + /* add interface and open for business */ + ret = brcmf_add_if(dev, 0, "wlan%d", NULL); + if (ret) { + brcmf_dbg(ERROR, "Add primary net device interface failed!!\n"); + brcmf_detach(dev); + goto fail; + } + + return 0; +fail: + /* Release resources in reverse order */ + if (bus_pub) + brcmf_usb_detach(bus_pub); + kfree(bus); + return ret; +} + +static void +brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub) +{ + if (!bus_pub) + return; + brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub); + + brcmf_detach(bus_pub->devinfo->dev); + kfree(bus_pub->bus); + brcmf_usb_detach(bus_pub); + +} + +static int +brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + int ep; + struct usb_endpoint_descriptor *endpoint; + int ret = 0; + struct usb_device *usb = interface_to_usbdev(intf); + int num_of_eps; + u8 endpoint_num; + + brcmf_dbg(TRACE, "enter\n"); + + usbdev_probe_info.usb = usb; + usbdev_probe_info.intf = intf; + + if (id != NULL) { + usbdev_probe_info.vid = id->idVendor; + usbdev_probe_info.pid = id->idProduct; + } + + usb_set_intfdata(intf, &usbdev_probe_info); + + /* Check that the device supports only one configuration */ + if (usb->descriptor.bNumConfigurations != 1) { + ret = -1; + goto fail; + } + + if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) { + ret = -1; + goto fail; + } + + /* + * Only the BDC interface configuration is supported: + * Device class: USB_CLASS_VENDOR_SPEC + * if0 class: USB_CLASS_VENDOR_SPEC + * if0/ep0: control + * if0/ep1: bulk in + * if0/ep2: bulk out (ok if swapped with bulk in) + */ + if (CONFIGDESC(usb)->bNumInterfaces != 1) { + ret = -1; + goto fail; + } + + /* Check interface */ + if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC || + IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 || + IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) { + brcmf_dbg(ERROR, "invalid control interface: class %d, subclass %d, proto %d\n", + IFDESC(usb, CONTROL_IF).bInterfaceClass, + IFDESC(usb, CONTROL_IF).bInterfaceSubClass, + IFDESC(usb, CONTROL_IF).bInterfaceProtocol); + ret = -1; + goto fail; + } + + /* Check control endpoint */ + endpoint = &IFEPDESC(usb, CONTROL_IF, 0); + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_INT) { + brcmf_dbg(ERROR, "invalid control endpoint %d\n", + endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); + ret = -1; + goto fail; + } + + endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num); + + usbdev_probe_info.rx_pipe = 0; + usbdev_probe_info.rx_pipe2 = 0; + usbdev_probe_info.tx_pipe = 0; + num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1; + + /* Check data endpoints and get pipes */ + for (ep = 1; ep <= num_of_eps; ep++) { + endpoint = &IFEPDESC(usb, BULK_IF, ep); + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != + USB_ENDPOINT_XFER_BULK) { + brcmf_dbg(ERROR, "invalid data endpoint %d\n", ep); + ret = -1; + goto fail; + } + + endpoint_num = endpoint->bEndpointAddress & + USB_ENDPOINT_NUMBER_MASK; + if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_IN) { + if (!usbdev_probe_info.rx_pipe) { + usbdev_probe_info.rx_pipe = + usb_rcvbulkpipe(usb, endpoint_num); + } else { + usbdev_probe_info.rx_pipe2 = + usb_rcvbulkpipe(usb, endpoint_num); + } + } else { + usbdev_probe_info.tx_pipe = + usb_sndbulkpipe(usb, endpoint_num); + } + } + + /* Allocate interrupt URB and data buffer */ + /* RNDIS says 8-byte intr, our old drivers used 4-byte */ + if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16)) + usbdev_probe_info.intr_size = 8; + else + usbdev_probe_info.intr_size = 4; + + usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; + + usbdev_probe_info.device_speed = usb->speed; + if (usb->speed == USB_SPEED_HIGH) + brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); + else + brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); + + ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0); + if (ret) + goto fail; + + /* Success */ + return 0; + +fail: + brcmf_dbg(ERROR, "failed with errno %d\n", ret); + usb_set_intfdata(intf, NULL); + return ret; + +} + +static void +brcmf_usb_disconnect(struct usb_interface *intf) +{ + struct usb_device *usb = interface_to_usbdev(intf); + + brcmf_dbg(TRACE, "enter\n"); + brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev)); + usb_set_intfdata(intf, NULL); +} + +/* + * only need to signal the bus being down and update the suspend state. + */ +static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) +{ + struct usb_device *usb = interface_to_usbdev(intf); + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); + + brcmf_dbg(TRACE, "enter\n"); + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN; + devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED; + return 0; +} + +/* + * mark suspend state active and crank up the bus. + */ +static int brcmf_usb_resume(struct usb_interface *intf) +{ + struct usb_device *usb = interface_to_usbdev(intf); + struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); + + brcmf_dbg(TRACE, "enter\n"); + devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE; + brcmf_bus_start(&usb->dev); + return 0; +} + +#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c +#define BRCMF_USB_DEVICE_ID_43236 0xbd17 +#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc + +static struct usb_device_id brcmf_usb_devid_table[] = { + { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) }, + /* special entry for device with firmware loaded and running */ + { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, + { } +}; +MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table); +MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); + +/* TODO: suspend and resume entries */ +static struct usb_driver brcmf_usbdrvr = { + .name = KBUILD_MODNAME, + .probe = brcmf_usb_probe, + .disconnect = brcmf_usb_disconnect, + .id_table = brcmf_usb_devid_table, + .suspend = brcmf_usb_suspend, + .resume = brcmf_usb_resume, + .supports_autosuspend = 1 +}; + +void brcmf_usb_exit(void) +{ + usb_deregister(&brcmf_usbdrvr); + kfree(g_image.data); + g_image.data = NULL; + g_image.len = 0; +} + +void brcmf_usb_init(void) +{ + usb_register(&brcmf_usbdrvr); +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h new file mode 100644 index 00000000000..acfa5e89872 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BRCMFMAC_USB_H +#define BRCMFMAC_USB_H + +enum brcmf_usb_state { + BCMFMAC_USB_STATE_DL_PENDING, + BCMFMAC_USB_STATE_DL_DONE, + BCMFMAC_USB_STATE_UP, + BCMFMAC_USB_STATE_DOWN, + BCMFMAC_USB_STATE_PNP_FWDL, + BCMFMAC_USB_STATE_DISCONNECT, + BCMFMAC_USB_STATE_SLEEP +}; + +enum brcmf_usb_pnp_state { + BCMFMAC_USB_PNP_DISCONNECT, + BCMFMAC_USB_PNP_SLEEP, + BCMFMAC_USB_PNP_RESUME, +}; + +struct brcmf_stats { + u32 tx_ctlpkts; + u32 tx_ctlerrs; + u32 rx_ctlpkts; + u32 rx_ctlerrs; +}; + +struct brcmf_usbdev { + struct brcmf_bus *bus; + struct brcmf_usbdev_info *devinfo; + enum brcmf_usb_state state; + struct brcmf_stats stats; + int ntxq, nrxq, rxsize; + u32 bus_mtu; + int devid; + int chiprev; /* chip revsion number */ +}; + +/* IO Request Block (IRB) */ +struct brcmf_usbreq { + struct list_head list; + struct brcmf_usbdev_info *devinfo; + struct urb *urb; + struct sk_buff *skb; +}; + +#endif /* BRCMFMAC_USB_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h new file mode 100644 index 00000000000..0a35c51c3da --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb_rdl.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _USB_RDL_H +#define _USB_RDL_H + +/* Control messages: bRequest values */ +#define DL_GETSTATE 0 /* returns the rdl_state_t struct */ +#define DL_CHECK_CRC 1 /* currently unused */ +#define DL_GO 2 /* execute downloaded image */ +#define DL_START 3 /* initialize dl state */ +#define DL_REBOOT 4 /* reboot the device in 2 seconds */ +#define DL_GETVER 5 /* returns the bootrom_id_t struct */ +#define DL_GO_PROTECTED 6 /* execute the downloaded code and set reset + * event to occur in 2 seconds. It is the + * responsibility of the downloaded code to + * clear this event + */ +#define DL_EXEC 7 /* jump to a supplied address */ +#define DL_RESETCFG 8 /* To support single enum on dongle + * - Not used by bootloader + */ +#define DL_DEFER_RESP_OK 9 /* Potentially defer the response to setup + * if resp unavailable + */ + +/* states */ +#define DL_WAITING 0 /* waiting to rx first pkt */ +#define DL_READY 1 /* hdr was good, waiting for more of the + * compressed image */ +#define DL_BAD_HDR 2 /* hdr was corrupted */ +#define DL_BAD_CRC 3 /* compressed image was corrupted */ +#define DL_RUNNABLE 4 /* download was successful,waiting for go cmd */ +#define DL_START_FAIL 5 /* failed to initialize correctly */ +#define DL_NVRAM_TOOBIG 6 /* host specified nvram data exceeds DL_NVRAM + * value */ +#define DL_IMAGE_TOOBIG 7 /* download image too big (exceeds DATA_START + * for rdl) */ + +struct rdl_state_le { + __le32 state; + __le32 bytes; +}; + +struct bootrom_id_le { + __le32 chip; /* Chip id */ + __le32 chiprev; /* Chip rev */ + __le32 ramsize; /* Size of RAM */ + __le32 remapbase; /* Current remap base address */ + __le32 boardtype; /* Type of board */ + __le32 boardrev; /* Board revision */ +}; + +#define RDL_CHUNK 1500 /* size of each dl transfer */ + +#define TRX_OFFSETS_DLFWLEN_IDX 0 +#define TRX_OFFSETS_JUMPTO_IDX 1 +#define TRX_OFFSETS_NVM_LEN_IDX 2 + +#define TRX_OFFSETS_DLBASE_IDX 0 + +#endif /* _USB_RDL_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index bf11850a20f..d13ae9c299f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,6 +16,8 @@ /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/if_arp.h> #include <linux/sched.h> @@ -1374,7 +1376,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, memset(&join_params, 0, sizeof(join_params)); join_params_size = sizeof(join_params.ssid_le); - ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len); + ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len); memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len); memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len); join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); @@ -2001,7 +2003,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, s32 err = 0; u16 channel; u32 freq; - u64 notify_timestamp; u16 notify_capability; u16 notify_interval; u8 *notify_ie; @@ -2024,7 +2025,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); - notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ notify_capability = le16_to_cpu(bi->capability); notify_interval = le16_to_cpu(bi->beacon_period); notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); @@ -2038,10 +2038,9 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, WL_CONN("Capability: %X\n", notify_capability); WL_CONN("Beacon interval: %d\n", notify_interval); WL_CONN("Signal: %d\n", notify_signal); - WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID, - notify_timestamp, notify_capability, notify_interval, notify_ie, + 0, notify_capability, notify_interval, notify_ie, notify_ielen, notify_signal, GFP_KERNEL); if (!bss) @@ -2096,7 +2095,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, s32 err = 0; u16 channel; u32 freq; - u64 notify_timestamp; u16 notify_capability; u16 notify_interval; u8 *notify_ie; @@ -2132,7 +2130,6 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, freq = ieee80211_channel_to_frequency(channel, band->band); notify_channel = ieee80211_get_channel(wiphy, freq); - notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */ notify_capability = le16_to_cpu(bi->capability); notify_interval = le16_to_cpu(bi->beacon_period); notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset); @@ -2143,10 +2140,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, WL_CONN("capability: %X\n", notify_capability); WL_CONN("beacon interval: %d\n", notify_interval); WL_CONN("signal: %d\n", notify_signal); - WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp); bss = cfg80211_inform_bss(wiphy, notify_channel, bssid, - notify_timestamp, notify_capability, notify_interval, + 0, notify_capability, notify_interval, notify_ie, notify_ielen, notify_signal, GFP_KERNEL); if (!bss) { @@ -2783,7 +2779,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_priv) + sizeof_iface); if (!wdev->wiphy) { - WL_ERR("Couldn not allocate wiphy device\n"); + WL_ERR("Could not allocate wiphy device\n"); err = -ENOMEM; goto wiphy_new_out; } @@ -2809,7 +2805,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, */ err = wiphy_register(wdev->wiphy); if (err < 0) { - WL_ERR("Couldn not register wiphy device (%d)\n", err); + WL_ERR("Could not register wiphy device (%d)\n", err); goto wiphy_register_out; } return wdev; @@ -3295,7 +3291,9 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event( } /* -** push event to tail of the queue +* push event to tail of the queue +* +* remark: this function may not sleep as it is called in atomic context. */ static s32 @@ -3304,17 +3302,18 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event, { struct brcmf_cfg80211_event_q *e; s32 err = 0; + ulong flags; - e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL); + e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC); if (!e) return -ENOMEM; e->etype = event; memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); - spin_lock_irq(&cfg_priv->evt_q_lock); + spin_lock_irqsave(&cfg_priv->evt_q_lock, flags); list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list); - spin_unlock_irq(&cfg_priv->evt_q_lock); + spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags); return err; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index a613b49cb13..b5d9b36df3d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -32,63 +32,63 @@ struct brcmf_cfg80211_ibss; #define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \ (WL_DBG_SCAN) | (WL_DBG_CONN)) -#define WL_ERR(fmt, args...) \ +#define WL_ERR(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_ERR) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "ERROR @%s : " fmt, \ - __func__, ##args); \ + pr_err("ERROR @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#if (defined BCMDBG) -#define WL_INFO(fmt, args...) \ +#if (defined DEBUG) +#define WL_INFO(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_INFO) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "INFO @%s : " fmt, \ - __func__, ##args); \ + pr_err("INFO @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_TRACE(fmt, args...) \ +#define WL_TRACE(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_TRACE) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "TRACE @%s : " fmt, \ - __func__, ##args); \ + pr_err("TRACE @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_SCAN(fmt, args...) \ +#define WL_SCAN(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_SCAN) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "SCAN @%s : " fmt, \ - __func__, ##args); \ + pr_err("SCAN @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_CONN(fmt, args...) \ +#define WL_CONN(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_CONN) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "CONN @%s : " fmt, \ - __func__, ##args); \ + pr_err("CONN @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#else /* (defined BCMDBG) */ +#else /* (defined DEBUG) */ #define WL_INFO(fmt, args...) #define WL_TRACE(fmt, args...) #define WL_SCAN(fmt, args...) #define WL_CONN(fmt, args...) -#endif /* (defined BCMDBG) */ +#endif /* (defined DEBUG) */ #define WL_NUM_SCAN_MAX 1 #define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index ab9bb11abfb..c93ea35bcee 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -326,11 +326,11 @@ #define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID)) -#ifdef BCMDBG +#ifdef DEBUG #define SI_MSG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__) #else #define SI_MSG(fmt, ...) no_printk(fmt, ##__VA_ARGS__) -#endif /* BCMDBG */ +#endif /* DEBUG */ #define GOODCOREADDR(x, b) \ (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 30b58870b1b..95b5902bc4b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -915,7 +915,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); struct wiphy *wiphy = wlc->wiphy; -#ifdef BCMDBG +#ifdef DEBUG u8 hole[AMPDU_MAX_MPDU]; memset(hole, 0, sizeof(hole)); #endif @@ -959,14 +959,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (supr_status) { update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { - wiphy_err(wiphy, "%s: Pkt tx suppressed, " - "illegal channel possibly %d\n", + wiphy_err(wiphy, + "%s: Pkt tx suppressed, illegal channel possibly %d\n", __func__, CHSPEC_CHANNEL( wlc->default_bss->chanspec)); } else { if (supr_status != TX_STATUS_SUPR_FRAG) - wiphy_err(wiphy, "%s:" - "supr_status 0x%x\n", + wiphy_err(wiphy, "%s: supr_status 0x%x\n", __func__, supr_status); } /* no need to retry for badch; will fail again */ @@ -988,9 +987,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, } } else if (txs->phyerr) { update_rate = false; - wiphy_err(wiphy, "wl%d: ampdu tx phy " - "error (0x%x)\n", wlc->pub->unit, - txs->phyerr); + wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", + __func__, txs->phyerr); if (brcm_msg_level & LOG_ERROR_VAL) { brcmu_prpkt("txpkt (AMPDU)", p); @@ -1018,10 +1016,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ack_recd = false; if (ba_recd) { bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - BCMMSG(wlc->wiphy, "tid %d seq %d," - " start_seq %d, bindex %d set %d, index %d\n", - tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); + BCMMSG(wiphy, + "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", + tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) && isset(bitmap, bindex)) { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 2e90a9a16ed..11054ae9d4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -177,7 +177,7 @@ #define BCMEXTRAHDROOM 172 /* debug/trace */ -#ifdef BCMDBG +#ifdef DEBUG #define DMA_ERROR(fmt, ...) \ do { \ if (*di->msg_level & 1) \ @@ -193,7 +193,7 @@ do { \ no_printk(fmt, ##__VA_ARGS__) #define DMA_TRACE(fmt, ...) \ no_printk(fmt, ##__VA_ARGS__) -#endif /* BCMDBG */ +#endif /* DEBUG */ #define DMA_NONE(fmt, ...) \ no_printk(fmt, ##__VA_ARGS__) @@ -968,7 +968,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) pktcnt++; } -#ifdef BCMDBG +#ifdef DEBUG if (resid > 0) { uint cur; cur = @@ -979,7 +979,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", di->rxin, di->rxout, cur); } -#endif /* BCMDBG */ +#endif /* DEBUG */ if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR("%s: bad frame length (%d)\n", diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 448ab9c4eb4..569ab8abd2a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -15,6 +15,7 @@ */ #define __UNDEF_NO_VERSION__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/etherdevice.h> #include <linux/sched.h> @@ -96,10 +97,10 @@ static struct bcma_device_id brcms_coreid_table[] = { }; MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); -#ifdef BCMDBG +#ifdef DEBUG static int msglevel = 0xdeadbeef; module_param(msglevel, int, 0); -#endif /* BCMDBG */ +#endif /* DEBUG */ static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), @@ -857,7 +858,7 @@ static void brcms_free(struct brcms_info *wl) /* free timers */ for (t = wl->timers; t; t = next) { next = t->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); @@ -1121,8 +1122,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev) wl = brcms_attach(pdev); if (!wl) { - pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME, - __func__); + pr_err("%s: brcms_attach failed!\n", __func__); return -ENODEV; } return 0; @@ -1136,8 +1136,8 @@ static int brcms_suspend(struct bcma_device *pdev) hw = bcma_get_drvdata(pdev); wl = hw->priv; if (!wl) { - wiphy_err(wl->wiphy, - "brcms_suspend: bcma_get_drvdata failed\n"); + pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME, + __func__); return -ENODEV; } @@ -1169,25 +1169,31 @@ static struct bcma_driver brcms_bcma_driver = { /** * This is the main entry point for the brcmsmac driver. * - * This function determines if a device pointed to by pdev is a WL device, - * and if so, performs a brcms_attach() on it. - * + * This function is scheduled upon module initialization and + * does the driver registration, which result in brcms_bcma_probe() + * call resulting in the driver bringup. */ -static int __init brcms_module_init(void) +static void brcms_driver_init(struct work_struct *work) { - int error = -ENODEV; + int error; + + error = bcma_driver_register(&brcms_bcma_driver); + if (error) + pr_err("%s: register returned %d\n", __func__, error); +} -#ifdef BCMDBG +static DECLARE_WORK(brcms_driver_work, brcms_driver_init); + +static int __init brcms_module_init(void) +{ +#ifdef DEBUG if (msglevel != 0xdeadbeef) brcm_msg_level = msglevel; -#endif /* BCMDBG */ - - error = bcma_driver_register(&brcms_bcma_driver); - printk(KERN_ERR "%s: register returned %d\n", __func__, error); - if (!error) - return 0; +#endif + if (!schedule_work(&brcms_driver_work)) + return -EBUSY; - return error; + return 0; } /** @@ -1199,6 +1205,7 @@ static int __init brcms_module_init(void) */ static void __exit brcms_module_exit(void) { + cancel_work_sync(&brcms_driver_work); bcma_driver_unregister(&brcms_bcma_driver); } @@ -1367,7 +1374,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl, t->next = wl->timers; wl->timers = t; -#ifdef BCMDBG +#ifdef DEBUG t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); if (t->name) strcpy(t->name, name); @@ -1386,7 +1393,7 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) { struct ieee80211_hw *hw = t->wl->pub->ieee_hw; -#ifdef BCMDBG +#ifdef DEBUG if (t->set) wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", __func__, t->name, periodic); @@ -1431,7 +1438,7 @@ void brcms_free_timer(struct brcms_timer *t) if (wl->timers == t) { wl->timers = wl->timers->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); @@ -1443,7 +1450,7 @@ void brcms_free_timer(struct brcms_timer *t) while (tmp) { if (tmp->next == t) { tmp->next = t->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 8f60419c37b..9358bd5ebd3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -40,7 +40,7 @@ struct brcms_timer { bool periodic; bool set; /* indicates if timer is active */ struct brcms_timer *next; /* for freeing on unload */ -#ifdef BCMDBG +#ifdef DEBUG char *name; /* Description of the timer */ #endif }; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index f6affc6fd12..231ddf4a674 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/pci_ids.h> #include <linux/if_ether.h> #include <net/mac80211.h> @@ -293,11 +295,11 @@ const u8 prio2fifo[NUMPRIO] = { /* debug/trace */ uint brcm_msg_level = -#if defined(BCMDBG) +#if defined(DEBUG) LOG_ERROR_VAL; #else 0; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* TX FIFO number to WME/802.1E Access Category */ static const u8 wme_fifo2ac[] = { @@ -342,14 +344,14 @@ static const u16 xmtfifo_sz[][NFIFO] = { {9, 58, 22, 14, 14, 5}, }; -#ifdef BCMDBG +#ifdef DEBUG static const char * const fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; #else static const char fifo_names[6][0]; #endif -#ifdef BCMDBG +#ifdef DEBUG /* pointer to most recently allocated wl/wlc */ static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif @@ -2899,7 +2901,6 @@ brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel) objoff += 2; return bcma_read16(core, objoff); -; } static void @@ -3075,30 +3076,30 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) { int i; struct macstat macstats; -#ifdef BCMDBG +#ifdef DEBUG u16 delta; u16 rxf0ovfl; u16 txfunfl[NFIFO]; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* if driver down, make no sense to update stats */ if (!wlc->pub->up) return; -#ifdef BCMDBG +#ifdef DEBUG /* save last rx fifo 0 overflow count */ rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; /* save last tx fifo underflow count */ for (i = 0; i < NFIFO; i++) txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Read mac stats from contiguous shared memory */ brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats, sizeof(struct macstat), OBJADDR_SHM_SEL); -#ifdef BCMDBG +#ifdef DEBUG /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) @@ -3114,7 +3115,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" "\n", wlc->pub->unit, delta, i); } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* merge counters from dma module */ for (i = 0; i < NFIFO; i++) { @@ -3246,7 +3247,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) } /* For old ucode, txfifo sizes needs to be modified(increased) */ - if (fifosz_fixup == true) + if (fifosz_fixup) brcms_b_corerev_fifofixup(wlc_hw); /* check txfifo allocations match between ucode and driver */ @@ -5425,7 +5426,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) return -EINVAL; /* update configuration value */ - if (config == true) + if (config) brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); /* Clear rateset override */ @@ -5765,62 +5766,49 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } -#ifdef BCMDBG -static const char * const supr_reason[] = { - "None", "PMQ Entry", "Flush request", - "Previous frag failure", "Channel mismatch", - "Lifetime Expiry", "Underflow" -}; - -static void brcms_c_print_txs_status(u16 s) -{ - printk(KERN_DEBUG "[15:12] %d frame attempts\n", - (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); - printk(KERN_DEBUG " [11:8] %d rts attempts\n", - (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT); - printk(KERN_DEBUG " [7] %d PM mode indicated\n", - ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printk(KERN_DEBUG " [6] %d intermediate status\n", - ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printk(KERN_DEBUG " [5] %d AMPDU\n", - (s & TX_STATUS_AMPDU) ? 1 : 0); - printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n", - ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), - supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printk(KERN_DEBUG " [1] %d acked\n", - ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); -} -#endif /* BCMDBG */ - void brcms_c_print_txstatus(struct tx_status *txs) { -#if defined(BCMDBG) - u16 s = txs->status; - u16 ackphyrxsh = txs->ackphyrxsh; - - printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n"); - - printk(KERN_DEBUG "FrameID: %04x ", txs->frameid); - printk(KERN_DEBUG "TxStatus: %04x", s); - printk(KERN_DEBUG "\n"); - - brcms_c_print_txs_status(s); - - printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); - printk(KERN_DEBUG "Seq: %04x ", txs->sequence); - printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr); - printk(KERN_DEBUG "RxAckRSSI: %04x ", - (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printk(KERN_DEBUG "RxAckSQ: %04x", - (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printk(KERN_DEBUG "\n"); -#endif /* defined(BCMDBG) */ + pr_debug("\ntxpkt (MPDU) Complete\n"); + + pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); + + pr_debug("[15:12] %d frame attempts\n", + (txs->status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + pr_debug(" [11:8] %d rts attempts\n", + (txs->status & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + pr_debug(" [7] %d PM mode indicated\n", + txs->status & TX_STATUS_PMINDCTD ? 1 : 0); + pr_debug(" [6] %d intermediate status\n", + txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); + pr_debug(" [5] %d AMPDU\n", + txs->status & TX_STATUS_AMPDU ? 1 : 0); + pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", + (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, + (const char *[]) { + "None", + "PMQ Entry", + "Flush request", + "Previous frag failure", + "Channel mismatch", + "Lifetime Expiry", + "Underflow" + } [(txs->status & TX_STATUS_SUPR_MASK) >> + TX_STATUS_SUPR_SHIFT]); + pr_debug(" [1] %d acked\n", + txs->status & TX_STATUS_ACK_RCV ? 1 : 0); + + pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", + txs->lasttxtime, txs->sequence, txs->phyerr, + (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, + (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); } bool brcms_c_chipmatch(u16 vendor, u16 device) { if (vendor != PCI_VENDOR_ID_BROADCOM) { - pr_err("chipmatch: unknown vendor id %04x\n", vendor); + pr_err("unknown vendor id %04x\n", vendor); return false; } @@ -5833,11 +5821,11 @@ bool brcms_c_chipmatch(u16 vendor, u16 device) if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; - pr_err("chipmatch: unknown device id %04x\n", device); + pr_err("unknown device id %04x\n", device); return false; } -#if defined(BCMDBG) +#if defined(DEBUG) void brcms_c_print_txdesc(struct d11txh *txh) { u16 mtcl = le16_to_cpu(txh->MacTxControlLow); @@ -5871,57 +5859,56 @@ void brcms_c_print_txdesc(struct d11txh *txh) struct ieee80211_rts rts = txh->rts_frame; /* add plcp header along with txh descriptor */ - printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - txh, sizeof(struct d11txh) + 48); - - printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); - printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); - printk(KERN_DEBUG "FC: %04x ", mfc); - printk(KERN_DEBUG "FES Time: %04x\n", tfest); - printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw, + brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, + "Raw TxDesc + plcp header:\n"); + + pr_debug("TxCtlLow: %04x ", mtcl); + pr_debug("TxCtlHigh: %04x ", mtch); + pr_debug("FC: %04x ", mfc); + pr_debug("FES Time: %04x\n", tfest); + pr_debug("PhyCtl: %04x%s ", ptcw, (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1); - printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printk(KERN_DEBUG "MainRates: %04x ", mainrates); - printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); - printk(KERN_DEBUG "\n"); + pr_debug("PhyCtl_1: %04x ", ptcw_1); + pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + pr_debug("MainRates: %04x ", mainrates); + pr_debug("XtraFrameTypes: %04x ", xtraft); + pr_debug("\n"); print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, ra, sizeof(txh->TxFrameRA)); - printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); + pr_debug("Fb FES Time: %04x ", tfestfb); print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, rtspfb, sizeof(txh->RTSPLCPFallback)); - printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); + pr_debug("RTS DUR: %04x ", rtsdfb); print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, fragpfb, sizeof(txh->FragPLCPFallback)); - printk(KERN_DEBUG "DUR: %04x", fragdfb); - printk(KERN_DEBUG "\n"); + pr_debug("DUR: %04x", fragdfb); + pr_debug("\n"); - printk(KERN_DEBUG "MModeLen: %04x ", mmodelen); - printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen); + pr_debug("MModeLen: %04x ", mmodelen); + pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); - printk(KERN_DEBUG "FrameID: %04x\n", tfid); - printk(KERN_DEBUG "TxStatus: %04x\n", txs); + pr_debug("FrameID: %04x\n", tfid); + pr_debug("TxStatus: %04x\n", txs); - printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu); - printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte); - printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); - printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); + pr_debug("MaxNumMpdu: %04x\n", mnmpdu); + pr_debug("MaxAggbyte: %04x\n", mabyte); + pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); + pr_debug("MinByte: %04x\n", mmbyte); print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, rtsph, sizeof(txh->RTSPhyHeader)); print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, (u8 *)&rts, sizeof(txh->rts_frame)); - printk(KERN_DEBUG "\n"); + pr_debug("\n"); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ -#if defined(BCMDBG) +#if defined(DEBUG) static int brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, int len) @@ -5975,9 +5962,9 @@ brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, return (int)(p - buf); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ -#if defined(BCMDBG) +#if defined(DEBUG) void brcms_c_print_rxh(struct d11rxhdr *rxh) { u16 len = rxh->RxFrameSize; @@ -5999,24 +5986,22 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) {0, NULL} }; - printk(KERN_DEBUG "Raw RxDesc:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, - sizeof(struct d11rxhdr)); + brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len, + pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n", + pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr); - printk(KERN_DEBUG "RXMACaggtype: %x\n", + pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); + pr_debug("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); - printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); + pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) { @@ -8354,7 +8339,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, wlc->wiphy = wl->wiphy; pub = wlc->pub; -#if defined(BCMDBG) +#if defined(DEBUG) wlc_info_dbg = wlc; #endif diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index adb136ec1f0..8debc74c54e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -648,10 +648,12 @@ extern void brcms_c_print_txstatus(struct tx_status *txs); extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks); -#if defined(BCMDBG) +#if defined(DEBUG) extern void brcms_c_print_txdesc(struct d11txh *txh); #else -#define brcms_c_print_txdesc(a) +static inline void brcms_c_print_txdesc(struct d11txh *txh) +{ +} #endif extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index a16f1ab292f..39095741fd0 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/delay.h> #include <linux/cordic.h> @@ -17822,8 +17824,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) if (pi->sh->sromrev < 4) { idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = 13 * 4; - target_pwr_qtrdbm[1] = 13 * 4; a1[0] = -424; a1[1] = -424; b0[0] = 5612; @@ -17837,10 +17837,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) case WL_CHAN_FREQ_RANGE_2G: idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_2g; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_2g; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0; @@ -17851,10 +17847,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) case WL_CHAN_FREQ_RANGE_5GL: idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gl; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gl; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0; @@ -17865,10 +17857,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) case WL_CHAN_FREQ_RANGE_5GM: idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gm; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gm; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0; @@ -17879,10 +17867,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) case WL_CHAN_FREQ_RANGE_5GH: idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gh; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gh; a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1; a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1; b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0; @@ -17893,8 +17877,6 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) default: idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = 13 * 4; - target_pwr_qtrdbm[1] = 13 * 4; a1[0] = -424; a1[1] = -424; b0[0] = 5612; @@ -17905,6 +17887,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) } } + /* use the provided transmit power */ target_pwr_qtrdbm[0] = (s8) pi->tx_power_max; target_pwr_qtrdbm[1] = (s8) pi->tx_power_max; @@ -19987,12 +19970,11 @@ static void wlc_phy_radio_init_2057(struct brcms_phy *pi) switch (pi->pubpi.radiorev) { case 5: - if (pi->pubpi.radiover == 0x0) + if (NREV_IS(pi->pubpi.phy_rev, 8)) regs_2057_ptr = regs_2057_rev5; - else if (pi->pubpi.radiover == 0x1) + else if (NREV_IS(pi->pubpi.phy_rev, 9)) regs_2057_ptr = regs_2057_rev5v1; - else - break; + break; case 7: @@ -21462,7 +21444,7 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) if (NREV_GE(pi->pubpi.phy_rev, 3)) { u16 v0 = 0x211, v1 = 0x222, v2 = 0x144, v3 = 0x188; - if (lut_init == false) + if (!lut_init) return; if (pi->srom_fem2g.antswctrllut == 0) { @@ -26434,8 +26416,7 @@ cal_try: } if (bcmerror != 0) { - printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__, - cal_retry); + pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry); if (cal_retry < CAL_RETRY_CNT) { cal_retry++; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c index 56374364303..b96f4b9d74b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c @@ -621,7 +621,7 @@ static inline void cpu_to_le16_buf(u16 *buf, uint nwords) /* * convert binary srom data into linked list of srom variable items. */ -static void +static int _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) { struct brcms_srom_list_head *entry; @@ -638,6 +638,9 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) /* first store the srom revision */ entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); + if (!entry) + return -ENOMEM; + entry->varid = BRCMS_SROM_REV; entry->var_type = BRCMS_SROM_UNUMBER; entry->uval = sromrev; @@ -715,6 +718,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) entry = kzalloc(sizeof(struct brcms_srom_list_head) + extra_space, GFP_KERNEL); + if (!entry) + return -ENOMEM; entry->varid = id; entry->var_type = type; if (flags & SRFL_ETHADDR) { @@ -754,6 +759,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); + if (!entry) + return -ENOMEM; entry->varid = srv->varid+p; entry->var_type = BRCMS_SROM_UNUMBER; entry->uval = val; @@ -761,6 +768,7 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) } pb += psz; } + return 0; } /* @@ -906,7 +914,9 @@ int srom_var_init(struct si_pub *sih) INIT_LIST_HEAD(&sii->var_list); /* parse SROM into name=value pairs. */ - _initvars_srom_pci(sromrev, srom, &sii->var_list); + err = _initvars_srom_pci(sromrev, srom, &sii->var_list); + if (err) + srom_free_vars(sih); } errout: diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index b7537f70a79..b45ab34cdfd 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/netdevice.h> #include <linux/module.h> @@ -240,17 +242,35 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, } EXPORT_SYMBOL(brcmu_pktq_mdeq); -#if defined(BCMDBG) +#if defined(DEBUG) /* pretty hex print a pkt buffer chain */ void brcmu_prpkt(const char *msg, struct sk_buff *p0) { struct sk_buff *p; if (msg && (msg[0] != '\0')) - printk(KERN_DEBUG "%s:\n", msg); + pr_debug("%s:\n", msg); for (p = p0; p; p = p->next) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } EXPORT_SYMBOL(brcmu_prpkt); -#endif /* defined(BCMDBG) */ + +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_debug("%pV", &vaf); + + va_end(args); + + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size); +} +EXPORT_SYMBOL(brcmu_dbg_hex_dump); +#endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index ad249a0b473..477b92ad3d6 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -176,10 +176,21 @@ struct ipv4_addr; /* externs */ /* format/print */ -#ifdef BCMDBG +#ifdef DEBUG extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) -#endif /* BCMDBG */ +#endif /* DEBUG */ + +#ifdef DEBUG +extern __printf(3, 4) +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...); +#else +__printf(3, 4) +static inline +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) +{ +} +#endif #endif /* _BRCMU_UTILS_H_ */ diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index a8bddd81b4d..aa15cc4269a 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -347,11 +347,9 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0, return -EINTR; entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n", - dev->name); + if (entry == NULL) return -ENOMEM; - } + atomic_set(&entry->usecnt, 1); entry->type = CMD_SLEEP; entry->cmd = cmd; @@ -515,11 +513,9 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0, } entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc " - "failed\n", dev->name); + if (entry == NULL) return -ENOMEM; - } + atomic_set(&entry->usecnt, 1); entry->type = CMD_CALLBACK; entry->cmd = cmd; @@ -2978,11 +2974,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set) local = iface->local; new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC); - if (new_entry == NULL) { - printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n", - local->dev->name); + if (new_entry == NULL) return -ENOMEM; - } + new_entry->aid = aid; new_entry->set = set; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index a0e5c21d365..f0551f807f6 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -298,8 +298,6 @@ static const char *command_types[] = { }; #endif -#define WEXT_USECHANNELS 1 - static const long ipw2100_frequencies[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, @@ -309,13 +307,6 @@ static const long ipw2100_frequencies[] = { #define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) -static const long ipw2100_rates_11b[] = { - 1000000, - 2000000, - 5500000, - 11000000 -}; - static struct ieee80211_rate ipw2100_bg_rates[] = { { .bitrate = 10 }, { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, @@ -323,7 +314,7 @@ static struct ieee80211_rate ipw2100_bg_rates[] = { { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, }; -#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b) +#define RATE_COUNT ARRAY_SIZE(ipw2100_bg_rates) /* Pre-decl until we get the code solid and then we can clean it up */ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); @@ -3464,11 +3455,8 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv) priv->msg_buffers = kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), GFP_KERNEL); - if (!priv->msg_buffers) { - printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " - "buffers.\n", priv->net_dev->name); + if (!priv->msg_buffers) return -ENOMEM; - } for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { v = pci_alloc_consistent(priv->pci_dev, @@ -6896,7 +6884,7 @@ static int ipw2100_wx_get_range(struct net_device *dev, range->num_bitrates = RATE_COUNT; for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { - range->bitrate[i] = ipw2100_rates_11b[i]; + range->bitrate[i] = ipw2100_bg_rates[i].bitrate * 100 * 1000; } range->min_rts = MIN_RTS_THRESHOLD; @@ -8108,61 +8096,41 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev, #endif /* CONFIG_IPW2100_MONITOR */ static iw_handler ipw2100_wx_handlers[] = { - NULL, /* SIOCSIWCOMMIT */ - ipw2100_wx_get_name, /* SIOCGIWNAME */ - NULL, /* SIOCSIWNWID */ - NULL, /* SIOCGIWNWID */ - ipw2100_wx_set_freq, /* SIOCSIWFREQ */ - ipw2100_wx_get_freq, /* SIOCGIWFREQ */ - ipw2100_wx_set_mode, /* SIOCSIWMODE */ - ipw2100_wx_get_mode, /* SIOCGIWMODE */ - NULL, /* SIOCSIWSENS */ - NULL, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - ipw2100_wx_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - NULL, /* SIOCSIWSPY */ - NULL, /* SIOCGIWSPY */ - NULL, /* SIOCGIWTHRSPY */ - NULL, /* SIOCWIWTHRSPY */ - ipw2100_wx_set_wap, /* SIOCSIWAP */ - ipw2100_wx_get_wap, /* SIOCGIWAP */ - ipw2100_wx_set_mlme, /* SIOCSIWMLME */ - NULL, /* SIOCGIWAPLIST -- deprecated */ - ipw2100_wx_set_scan, /* SIOCSIWSCAN */ - ipw2100_wx_get_scan, /* SIOCGIWSCAN */ - ipw2100_wx_set_essid, /* SIOCSIWESSID */ - ipw2100_wx_get_essid, /* SIOCGIWESSID */ - ipw2100_wx_set_nick, /* SIOCSIWNICKN */ - ipw2100_wx_get_nick, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - ipw2100_wx_set_rate, /* SIOCSIWRATE */ - ipw2100_wx_get_rate, /* SIOCGIWRATE */ - ipw2100_wx_set_rts, /* SIOCSIWRTS */ - ipw2100_wx_get_rts, /* SIOCGIWRTS */ - ipw2100_wx_set_frag, /* SIOCSIWFRAG */ - ipw2100_wx_get_frag, /* SIOCGIWFRAG */ - ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */ - ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */ - ipw2100_wx_set_retry, /* SIOCSIWRETRY */ - ipw2100_wx_get_retry, /* SIOCGIWRETRY */ - ipw2100_wx_set_encode, /* SIOCSIWENCODE */ - ipw2100_wx_get_encode, /* SIOCGIWENCODE */ - ipw2100_wx_set_power, /* SIOCSIWPOWER */ - ipw2100_wx_get_power, /* SIOCGIWPOWER */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - ipw2100_wx_set_genie, /* SIOCSIWGENIE */ - ipw2100_wx_get_genie, /* SIOCGIWGENIE */ - ipw2100_wx_set_auth, /* SIOCSIWAUTH */ - ipw2100_wx_get_auth, /* SIOCGIWAUTH */ - ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */ - ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */ - NULL, /* SIOCSIWPMKSA */ + IW_HANDLER(SIOCGIWNAME, ipw2100_wx_get_name), + IW_HANDLER(SIOCSIWFREQ, ipw2100_wx_set_freq), + IW_HANDLER(SIOCGIWFREQ, ipw2100_wx_get_freq), + IW_HANDLER(SIOCSIWMODE, ipw2100_wx_set_mode), + IW_HANDLER(SIOCGIWMODE, ipw2100_wx_get_mode), + IW_HANDLER(SIOCGIWRANGE, ipw2100_wx_get_range), + IW_HANDLER(SIOCSIWAP, ipw2100_wx_set_wap), + IW_HANDLER(SIOCGIWAP, ipw2100_wx_get_wap), + IW_HANDLER(SIOCSIWMLME, ipw2100_wx_set_mlme), + IW_HANDLER(SIOCSIWSCAN, ipw2100_wx_set_scan), + IW_HANDLER(SIOCGIWSCAN, ipw2100_wx_get_scan), + IW_HANDLER(SIOCSIWESSID, ipw2100_wx_set_essid), + IW_HANDLER(SIOCGIWESSID, ipw2100_wx_get_essid), + IW_HANDLER(SIOCSIWNICKN, ipw2100_wx_set_nick), + IW_HANDLER(SIOCGIWNICKN, ipw2100_wx_get_nick), + IW_HANDLER(SIOCSIWRATE, ipw2100_wx_set_rate), + IW_HANDLER(SIOCGIWRATE, ipw2100_wx_get_rate), + IW_HANDLER(SIOCSIWRTS, ipw2100_wx_set_rts), + IW_HANDLER(SIOCGIWRTS, ipw2100_wx_get_rts), + IW_HANDLER(SIOCSIWFRAG, ipw2100_wx_set_frag), + IW_HANDLER(SIOCGIWFRAG, ipw2100_wx_get_frag), + IW_HANDLER(SIOCSIWTXPOW, ipw2100_wx_set_txpow), + IW_HANDLER(SIOCGIWTXPOW, ipw2100_wx_get_txpow), + IW_HANDLER(SIOCSIWRETRY, ipw2100_wx_set_retry), + IW_HANDLER(SIOCGIWRETRY, ipw2100_wx_get_retry), + IW_HANDLER(SIOCSIWENCODE, ipw2100_wx_set_encode), + IW_HANDLER(SIOCGIWENCODE, ipw2100_wx_get_encode), + IW_HANDLER(SIOCSIWPOWER, ipw2100_wx_set_power), + IW_HANDLER(SIOCGIWPOWER, ipw2100_wx_get_power), + IW_HANDLER(SIOCSIWGENIE, ipw2100_wx_set_genie), + IW_HANDLER(SIOCGIWGENIE, ipw2100_wx_get_genie), + IW_HANDLER(SIOCSIWAUTH, ipw2100_wx_set_auth), + IW_HANDLER(SIOCGIWAUTH, ipw2100_wx_get_auth), + IW_HANDLER(SIOCSIWENCODEEXT, ipw2100_wx_set_encodeext), + IW_HANDLER(SIOCGIWENCODEEXT, ipw2100_wx_get_encodeext), }; #define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h index ecb561d7a7a..570d6fb8896 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.h +++ b/drivers/net/wireless/ipw2x00/ipw2200.h @@ -27,8 +27,6 @@ #ifndef __ipw2200_h__ #define __ipw2200_h__ -#define WEXT_USECHANNELS 1 - #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> @@ -1999,18 +1997,6 @@ struct ipw_cmd_log { #define CFG_SYS_ANTENNA_B 0x03 /* force antenna B */ #define CFG_SYS_ANTENNA_SLOW_DIV 0x02 /* consider background noise */ -/* - * The definitions below were lifted off the ipw2100 driver, which only - * supports 'b' mode, so I'm sure these are not exactly correct. - * - * Somebody fix these!! - */ -#define REG_MIN_CHANNEL 0 -#define REG_MAX_CHANNEL 14 - -#define REG_CHANNEL_MASK 0x00003FFF -#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff - #define IPW_MAX_CONFIG_RETRIES 10 #endif /* __ipw2200_h__ */ diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index d5ef696298e..3adb24021a2 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -150,10 +150,9 @@ struct net_device *alloc_libipw(int sizeof_priv, int monitor) LIBIPW_DEBUG_INFO("Initializing...\n"); dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv); - if (!dev) { - LIBIPW_ERROR("Unable to allocate network device.\n"); + if (!dev) goto failed; - } + ieee = netdev_priv(dev); ieee->dev = dev; diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 32a9966c3bf..c4955d25a19 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c @@ -172,7 +172,7 @@ libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb, u16 stype) { if (ieee->iw_mode == IW_MODE_MASTER) { - printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", + printk(KERN_DEBUG "%s: Master mode not yet supported.\n", ieee->dev->name); return 0; /* diff --git a/drivers/net/wireless/iwlegacy/3945-debug.c b/drivers/net/wireless/iwlegacy/3945-debug.c index 5e1a19fd354..f767dd106b0 100644 --- a/drivers/net/wireless/iwlegacy/3945-debug.c +++ b/drivers/net/wireless/iwlegacy/3945-debug.c @@ -503,3 +503,9 @@ il3945_ucode_general_stats_read(struct file *file, char __user *user_buf, kfree(buf); return ret; } + +const struct il_debugfs_ops il3945_debugfs_ops = { + .rx_stats_read = il3945_ucode_rx_stats_read, + .tx_stats_read = il3945_ucode_tx_stats_read, + .general_stats_read = il3945_ucode_general_stats_read, +}; diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index a7dfba8d164..0c120939016 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -140,7 +140,7 @@ il3945_set_ccmp_dynamic_key_info(struct il_priv *il, key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - if (sta_id == il->ctx.bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -341,7 +341,7 @@ il3945_send_beacon_cmd(struct il_priv *il) return -ENOMEM; } - rate = il_get_lowest_plcp(il, &il->ctx); + rate = il_get_lowest_plcp(il); frame_size = il3945_hw_get_beacon_cmd(il, frame, rate); @@ -512,7 +512,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find idx into station table for destination station */ - sta_id = il_sta_id_or_broadcast(il, &il->ctx, info->control.sta); + sta_id = il_sta_id_or_broadcast(il, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); goto drop; @@ -538,10 +538,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) idx = il_get_cmd_idx(q, q->write_ptr, 0); - /* Set up driver data for this TFD */ - memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info)); - txq->txb[q->write_ptr].skb = skb; - txq->txb[q->write_ptr].ctx = &il->ctx; + txq->skbs[q->write_ptr] = skb; /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[idx]; @@ -576,7 +573,6 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) len = (u16) skb->len; tx_cmd->len = cpu_to_le16(len); - il_dbg_log_tx_data_frame(il, len, hdr); il_update_stats(il, true, fc, len); tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; @@ -619,8 +615,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, - 0); + il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); /* Set up TFD's 2nd entry to point directly to remainder of skb, * if any (802.11 null frames have no payload). */ @@ -629,8 +624,8 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) phys_addr = pci_map_single(il->pci_dev, skb->data + hdr_len, len, PCI_DMA_TODEVICE); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, - len, 0, U32_PAD(len)); + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, + U32_PAD(len)); } /* Tell device the write idx *just past* this latest filled TFD */ @@ -672,15 +667,13 @@ il3945_get_measurement(struct il_priv *il, int rc; int spectrum_resp_status; int duration = le16_to_cpu(params->duration); - struct il_rxon_context *ctx = &il->ctx; if (il_is_associated(il)) add_time = il_usecs_to_beacons(il, le64_to_cpu(params->start_time) - il->_3945.last_tsf, - le16_to_cpu(ctx->timing. - beacon_interval)); + le16_to_cpu(il->timing.beacon_interval)); memset(&spectrum, 0, sizeof(spectrum)); @@ -694,15 +687,14 @@ il3945_get_measurement(struct il_priv *il, if (il_is_associated(il)) spectrum.start_time = il_add_beacon_time(il, il->_3945.last_beacon_time, add_time, - le16_to_cpu(ctx->timing. - beacon_interval)); + le16_to_cpu(il->timing.beacon_interval)); else spectrum.start_time = 0; spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); spectrum.channels[0].channel = params->channel; spectrum.channels[0].type = type; - if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) + if (il->active.flags & RXON_FLG_BAND_24G_MSK) spectrum.flags |= RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; @@ -817,16 +809,16 @@ il3945_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb) _il_wr(il, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); if (flags & HW_CARD_DISABLED) - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); else - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); il_scan_cancel(il); - if ((test_bit(S_RF_KILL_HW, &status) != - test_bit(S_RF_KILL_HW, &il->status))) + if ((test_bit(S_RFKILL, &status) != + test_bit(S_RFKILL, &il->status))) wiphy_rfkill_set_hw_state(il->hw->wiphy, - test_bit(S_RF_KILL_HW, &il->status)); + test_bit(S_RFKILL, &il->status)); else wake_up(&il->wait_command_queue); } @@ -2150,7 +2142,6 @@ il3945_alive_start(struct il_priv *il) { int thermal_spin = 0; u32 rfkill; - struct il_rxon_context *ctx = &il->ctx; D_INFO("Runtime Alive received.\n"); @@ -2175,7 +2166,7 @@ il3945_alive_start(struct il_priv *il) D_INFO("RFKILL status: 0x%x\n", rfkill); if (rfkill & 0x1) { - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); /* if RFKILL is not on, then wait for thermal * sensor in adapter to kick in */ while (il3945_hw_get_temperature(il) == 0) { @@ -2187,7 +2178,7 @@ il3945_alive_start(struct il_priv *il) D_INFO("Thermal calibration took %dus\n", thermal_spin * 10); } else - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); /* After the ALIVE response, we can send commands to 3945 uCode */ set_bit(S_ALIVE, &il->status); @@ -2206,13 +2197,13 @@ il3945_alive_start(struct il_priv *il) if (il_is_associated(il)) { struct il3945_rxon_cmd *active_rxon = - (struct il3945_rxon_cmd *)(&ctx->active); + (struct il3945_rxon_cmd *)(&il->active); - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - il_connection_init_rx_config(il, ctx); + il_connection_init_rx_config(il); } /* Configure Bluetooth device coexistence support */ @@ -2221,7 +2212,7 @@ il3945_alive_start(struct il_priv *il) set_bit(S_READY, &il->status); /* Configure the adapter for unassociated operation */ - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); il3945_reg_txpower_periodic(il); @@ -2253,7 +2244,7 @@ __il3945_down(struct il_priv *il) del_timer_sync(&il->watchdog); /* Station information will now be cleared in device */ - il_clear_ucode_stations(il, NULL); + il_clear_ucode_stations(il); il_dealloc_bcast_stations(il); il_clear_driver_stations(il); @@ -2281,12 +2272,8 @@ __il3945_down(struct il_priv *il) * clear all bits but the RF Kill bits and return */ if (!il_is_init(il)) { il->status = - test_bit(S_RF_KILL_HW, - &il-> - status) << S_RF_KILL_HW | - test_bit(S_GEO_CONFIGURED, - &il-> - status) << S_GEO_CONFIGURED | + test_bit(S_RFKILL, &il->status) << S_RFKILL | + test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED | test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; goto exit; } @@ -2294,25 +2281,30 @@ __il3945_down(struct il_priv *il) /* ...otherwise clear out all the status bits but the RF Kill * bit and continue taking the NIC down. */ il->status &= - test_bit(S_RF_KILL_HW, - &il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED, - &il-> - status) << - S_GEO_CONFIGURED | test_bit(S_FW_ERROR, - &il-> - status) << S_FW_ERROR | + test_bit(S_RFKILL, &il->status) << S_RFKILL | + test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED | + test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR | test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; + /* + * We disabled and synchronized interrupt, and priv->mutex is taken, so + * here is the only thread which will program device registers, but + * still have lockdep assertions, so we are taking reg_lock. + */ + spin_lock_irq(&il->reg_lock); + /* FIXME: il_grab_nic_access if rfkill is off ? */ + il3945_hw_txq_ctx_stop(il); il3945_hw_rxq_stop(il); - /* Power-down device's busmaster DMA clocks */ - il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); + _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(5); - /* Stop the device, and put it in low power state */ - il_apm_stop(il); + _il_apm_stop(il); + + spin_unlock_irq(&il->reg_lock); + il3945_hw_txq_ctx_free(il); exit: memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); @@ -2339,12 +2331,11 @@ il3945_down(struct il_priv *il) static int il3945_alloc_bcast_station(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; unsigned long flags; u8 sta_id; spin_lock_irqsave(&il->sta_lock, flags); - sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL); + sta_id = il_prep_station(il, il_bcast_addr, false, NULL); if (sta_id == IL_INVALID_STATION) { IL_ERR("Unable to prepare broadcast station\n"); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -2380,9 +2371,9 @@ __il3945_up(struct il_priv *il) /* If platform's RF_KILL switch is NOT set to KILL */ if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); else { - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); IL_WARN("Radio disabled by HW RF Kill switch\n"); return -ENODEV; } @@ -2414,7 +2405,7 @@ __il3945_up(struct il_priv *il) il->ucode_data.len); /* We return success when we resume from suspend and rf_kill is on. */ - if (test_bit(S_RF_KILL_HW, &il->status)) + if (test_bit(S_RFKILL, &il->status)) return 0; for (i = 0; i < MAX_HW_RESTARTS; i++) { @@ -2422,7 +2413,7 @@ __il3945_up(struct il_priv *il) /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - rc = il->cfg->ops->lib->load_ucode(il); + rc = il->ops->load_ucode(il); if (rc) { IL_ERR("Unable to set up bootstrap uCode: %d\n", rc); @@ -2494,15 +2485,15 @@ il3945_rfkill_poll(struct work_struct *data) { struct il_priv *il = container_of(data, struct il_priv, _3945.rfkill_poll.work); - bool old_rfkill = test_bit(S_RF_KILL_HW, &il->status); + bool old_rfkill = test_bit(S_RFKILL, &il->status); bool new_rfkill = !(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); if (new_rfkill != old_rfkill) { if (new_rfkill) - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); else - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); wiphy_rfkill_set_hw_state(il->hw->wiphy, new_rfkill); @@ -2602,7 +2593,7 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif) /* We don't build a direct scan probe request; the uCode will do * that based on the direct_mask added to each channel entry */ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = il->ctx.bcast_sta_id; + scan->tx_cmd.sta_id = il->hw_params.bcast_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; /* flags + rate selection */ @@ -2664,14 +2655,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif) void il3945_post_scan(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - /* * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - il3945_commit_rxon(il, ctx); + if (memcmp(&il->staging, &il->active, sizeof(il->staging))) + il3945_commit_rxon(il); } static void @@ -2684,7 +2673,8 @@ il3945_bg_restart(struct work_struct *data) if (test_and_clear_bit(S_FW_ERROR, &il->status)) { mutex_lock(&il->mutex); - il->ctx.vif = NULL; + /* FIXME: vif can be dereferenced */ + il->vif = NULL; il->is_open = 0; mutex_unlock(&il->mutex); il3945_down(il); @@ -2722,13 +2712,12 @@ il3945_post_associate(struct il_priv *il) { int rc = 0; struct ieee80211_conf *conf = NULL; - struct il_rxon_context *ctx = &il->ctx; - if (!ctx->vif || !il->is_open) + if (!il->vif || !il->is_open) return; - D_ASSOC("Associated as %d to: %pM\n", ctx->vif->bss_conf.aid, - ctx->active.bssid_addr); + D_ASSOC("Associated as %d to: %pM\n", il->vif->bss_conf.aid, + il->active.bssid_addr); if (test_bit(S_EXIT_PENDING, &il->status)) return; @@ -2737,35 +2726,35 @@ il3945_post_associate(struct il_priv *il) conf = &il->hw->conf; - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il3945_commit_rxon(il, ctx); + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il3945_commit_rxon(il); - rc = il_send_rxon_timing(il, ctx); + rc = il_send_rxon_timing(il); if (rc) IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n"); - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid); + il->staging.assoc_id = cpu_to_le16(il->vif->bss_conf.aid); - D_ASSOC("assoc id %d beacon interval %d\n", ctx->vif->bss_conf.aid, - ctx->vif->bss_conf.beacon_int); + D_ASSOC("assoc id %d beacon interval %d\n", il->vif->bss_conf.aid, + il->vif->bss_conf.beacon_int); - if (ctx->vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + if (il->vif->bss_conf.use_short_preamble) + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { - if (ctx->vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->vif->bss_conf.use_short_slot) + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - il3945_commit_rxon(il, ctx); + il3945_commit_rxon(il); - switch (ctx->vif->type) { + switch (il->vif->type) { case NL80211_IFTYPE_STATION: il3945_rate_scale_init(il->hw, IL_AP_ID); break; @@ -2774,7 +2763,7 @@ il3945_post_associate(struct il_priv *il) break; default: IL_ERR("%s Should not be called in %d mode\n", __func__, - ctx->vif->type); + il->vif->type); break; } } @@ -2793,10 +2782,9 @@ il3945_mac_start(struct ieee80211_hw *hw) struct il_priv *il = hw->priv; int ret; - D_MAC80211("enter\n"); - /* we should be verifying the device is ready to be opened */ mutex_lock(&il->mutex); + D_MAC80211("enter\n"); /* fetch ucode file from disk, alloc and copy to bus-master buffers ... * ucode filename and max sizes are card-specific. */ @@ -2891,8 +2879,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void il3945_config_ap(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; int rc = 0; if (test_bit(S_EXIT_PENDING, &il->status)) @@ -2902,31 +2889,31 @@ il3945_config_ap(struct il_priv *il) if (!(il_is_associated(il))) { /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il3945_commit_rxon(il, ctx); + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il3945_commit_rxon(il); /* RXON Timing */ - rc = il_send_rxon_timing(il, ctx); + rc = il_send_rxon_timing(il); if (rc) IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n"); - ctx->staging.assoc_id = 0; + il->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - il3945_commit_rxon(il, ctx); + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il3945_commit_rxon(il); } il3945_send_beacon_cmd(il); } @@ -2953,15 +2940,19 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * hardware will then not attempt to decrypt the frames. */ if (vif->type == NL80211_IFTYPE_ADHOC && - !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + D_MAC80211("leave - IBSS RSN\n"); return -EOPNOTSUPP; + } static_key = !il_is_associated(il); if (!static_key) { - sta_id = il_sta_id_or_broadcast(il, &il->ctx, sta); - if (sta_id == IL_INVALID_STATION) + sta_id = il_sta_id_or_broadcast(il, sta); + if (sta_id == IL_INVALID_STATION) { + D_MAC80211("leave - station not found\n"); return -EINVAL; + } } mutex_lock(&il->mutex); @@ -2986,8 +2977,8 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = -EINVAL; } + D_MAC80211("leave ret %d\n", ret); mutex_unlock(&il->mutex); - D_MAC80211("leave\n"); return ret; } @@ -3002,13 +2993,11 @@ il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool is_ap = vif->type == NL80211_IFTYPE_STATION; u8 sta_id; - D_INFO("received request to add station %pM\n", sta->addr); mutex_lock(&il->mutex); - D_INFO("proceeding to add station %pM\n", sta->addr); + D_INFO("station %pM\n", sta->addr); sta_priv->common.sta_id = IL_INVALID_STATION; - ret = - il_add_station_common(il, &il->ctx, sta->addr, is_ap, sta, &sta_id); + ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id); if (ret) { IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ @@ -3032,7 +3021,6 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, { struct il_priv *il = hw->priv; __le32 filter_or = 0, filter_nand = 0; - struct il_rxon_context *ctx = &il->ctx; #define CHK(test, flag) do { \ if (*total_flags & (test)) \ @@ -3052,8 +3040,8 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, mutex_lock(&il->mutex); - ctx->staging.filter_flags &= ~filter_nand; - ctx->staging.filter_flags |= filter_or; + il->staging.filter_flags &= ~filter_nand; + il->staging.filter_flags |= filter_or; /* * Not committing directly because hardware can perform a scan, @@ -3112,11 +3100,9 @@ il3945_store_debug_level(struct device *d, struct device_attribute *attr, ret = strict_strtoul(buf, 0, &val); if (ret) IL_INFO("%s is not in hex or decimal form.\n", buf); - else { + else il->debug_level = val; - if (il_alloc_traffic_mem(il)) - IL_ERR("Not enough memory to generate traffic log\n"); - } + return strnlen(buf, count); } @@ -3170,9 +3156,8 @@ static ssize_t il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; - return sprintf(buf, "0x%04X\n", ctx->active.flags); + return sprintf(buf, "0x%04X\n", il->active.flags); } static ssize_t @@ -3181,17 +3166,16 @@ il3945_store_flags(struct device *d, struct device_attribute *attr, { struct il_priv *il = dev_get_drvdata(d); u32 flags = simple_strtoul(buf, NULL, 0); - struct il_rxon_context *ctx = &il->ctx; mutex_lock(&il->mutex); - if (le32_to_cpu(ctx->staging.flags) != flags) { + if (le32_to_cpu(il->staging.flags) != flags) { /* Cancel any currently running scans... */ if (il_scan_cancel_timeout(il, 100)) IL_WARN("Could not cancel scan.\n"); else { D_INFO("Committing rxon.flags = 0x%04X\n", flags); - ctx->staging.flags = cpu_to_le32(flags); - il3945_commit_rxon(il, ctx); + il->staging.flags = cpu_to_le32(flags); + il3945_commit_rxon(il); } } mutex_unlock(&il->mutex); @@ -3207,9 +3191,8 @@ il3945_show_filter_flags(struct device *d, struct device_attribute *attr, char *buf) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; - return sprintf(buf, "0x%04X\n", le32_to_cpu(ctx->active.filter_flags)); + return sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags)); } static ssize_t @@ -3217,19 +3200,18 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; u32 filter_flags = simple_strtoul(buf, NULL, 0); mutex_lock(&il->mutex); - if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { + if (le32_to_cpu(il->staging.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ if (il_scan_cancel_timeout(il, 100)) IL_WARN("Could not cancel scan.\n"); else { D_INFO("Committing rxon.filter_flags = " "0x%04X\n", filter_flags); - ctx->staging.filter_flags = cpu_to_le32(filter_flags); - il3945_commit_rxon(il, ctx); + il->staging.filter_flags = cpu_to_le32(filter_flags); + il3945_commit_rxon(il); } } mutex_unlock(&il->mutex); @@ -3278,9 +3260,8 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { struct il_priv *il = dev_get_drvdata(d); - struct il_rxon_context *ctx = &il->ctx; struct ieee80211_measurement_params params = { - .channel = le16_to_cpu(ctx->active.channel), + .channel = le16_to_cpu(il->active.channel), .start_time = cpu_to_le64(il->_3945.last_tsf), .duration = cpu_to_le16(1), }; @@ -3474,7 +3455,7 @@ static struct attribute_group il3945_attribute_group = { .attrs = il3945_sysfs_entries, }; -struct ieee80211_ops il3945_hw_ops = { +struct ieee80211_ops il3945_mac_ops = { .tx = il3945_mac_tx, .start = il3945_mac_start, .stop = il3945_mac_stop, @@ -3567,7 +3548,8 @@ il3945_setup_mac(struct il_priv *il) /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; - hw->wiphy->interface_modes = il->ctx.interface_modes; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | @@ -3614,50 +3596,35 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 1. Allocating HW data * ********************/ - /* mac80211 allocates memory for this device instance, including - * space for this driver's ilate structure */ - hw = il_alloc_all(cfg); - if (hw == NULL) { - pr_err("Can not allocate network device\n"); + hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il3945_mac_ops); + if (!hw) { err = -ENOMEM; goto out; } il = hw->priv; + il->hw = hw; SET_IEEE80211_DEV(hw, &pdev->dev); il->cmd_queue = IL39_CMD_QUEUE_NUM; - il->ctx.ctxid = 0; - - il->ctx.rxon_cmd = C_RXON; - il->ctx.rxon_timing_cmd = C_RXON_TIMING; - il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; - il->ctx.qos_cmd = C_QOS_PARAM; - il->ctx.ap_sta_id = IL_AP_ID; - il->ctx.wep_key_cmd = C_WEPKEY; - il->ctx.interface_modes = - BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); - il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS; - il->ctx.station_devtype = RXON_DEV_TYPE_ESS; - il->ctx.unused_devtype = RXON_DEV_TYPE_ESS; - /* * Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. */ if (il3945_mod_params.disable_hw_scan) { D_INFO("Disabling hw_scan\n"); - il3945_hw_ops.hw_scan = NULL; + il3945_mac_ops.hw_scan = NULL; } D_INFO("*** LOAD DRIVER ***\n"); il->cfg = cfg; + il->ops = &il3945_ops; +#ifdef CONFIG_IWLEGACY_DEBUGFS + il->debugfs_ops = &il3945_debugfs_ops; +#endif il->pci_dev = pdev; il->inta_mask = CSR_INI_SET_MASK; - if (il_alloc_traffic_mem(il)) - IL_ERR("Not enough memory to generate traffic log\n"); - /*************************** * 2. Initializing PCI bus * *************************/ @@ -3688,7 +3655,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /*********************** * 3. Read REV Register * ********************/ - il->hw_base = pci_iomap(pdev, 0, 0); + il->hw_base = pci_ioremap_bar(pdev, 0); if (!il->hw_base) { err = -ENODEV; goto out_pci_release_regions; @@ -3702,7 +3669,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, 0x41, 0x00); - /* these spin locks will be used in apm_ops.init and EEPROM access + /* these spin locks will be used in apm_init and EEPROM access * we should init now */ spin_lock_init(&il->reg_lock); @@ -3773,8 +3740,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_release_irq; } - il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5], - &il->ctx); + il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5]); il3945_setup_deferred_work(il); il3945_setup_handlers(il); il_power_initialize(il); @@ -3814,14 +3780,13 @@ out_unset_hw_params: out_eeprom_free: il_eeprom_free(il); out_iounmap: - pci_iounmap(pdev, il->hw_base); + iounmap(il->hw_base); out_pci_release_regions: pci_release_regions(pdev); out_pci_disable_device: pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); out_ieee80211_free_hw: - il_free_traffic_mem(il); ieee80211_free_hw(il->hw); out: return err; @@ -3889,12 +3854,11 @@ il3945_pci_remove(struct pci_dev *pdev) * until now... */ destroy_workqueue(il->workqueue); il->workqueue = NULL; - il_free_traffic_mem(il); free_irq(pdev->irq, il); pci_disable_msi(pdev); - pci_iounmap(pdev, il->hw_base); + iounmap(il->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index d7a83f22919..70bee1a4d87 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c @@ -342,7 +342,7 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) int i; D_INFO("enter\n"); - if (sta_id == il->ctx.bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) goto out; psta = (struct il3945_sta_priv *)sta->drv_priv; @@ -927,8 +927,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) rcu_read_lock(); - sta = - ieee80211_find_sta(il->ctx.vif, il->stations[sta_id].sta.sta.addr); + sta = ieee80211_find_sta(il->vif, il->stations[sta_id].sta.sta.addr); if (!sta) { D_RATE("Unable to find station to initialize rate scaling.\n"); rcu_read_unlock(); @@ -944,7 +943,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) switch (il->band) { case IEEE80211_BAND_2GHZ: /* TODO: this always does G, not a regression */ - if (il->ctx.active.flags & RXON_FLG_TGG_PROTECT_MSK) { + if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) { rs_sta->tgg = 1; rs_sta->expected_tpt = il3945_expected_tpt_g_prot; } else diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index c80eb9b3155..c5b1d199e0b 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -57,10 +57,6 @@ il3945_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd) return il_send_cmd(il, &cmd); } -const struct il_led_ops il3945_led_ops = { - .cmd = il3945_send_led_cmd, -}; - #define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ [RATE_##r##M_IDX] = { RATE_##r##M_PLCP, \ RATE_##r##M_IEEE, \ @@ -293,17 +289,17 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) { struct il_tx_queue *txq = &il->txq[txq_id]; struct il_queue *q = &txq->q; - struct il_tx_info *tx_info; + struct sk_buff *skb; BUG_ON(txq_id == IL39_CMD_QUEUE_NUM); for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) { - tx_info = &txq->txb[txq->q.read_ptr]; - ieee80211_tx_status_irqsafe(il->hw, tx_info->skb); - tx_info->skb = NULL; - il->cfg->ops->lib->txq_free_tfd(il, txq); + skb = txq->skbs[txq->q.read_ptr]; + ieee80211_tx_status_irqsafe(il->hw, skb); + txq->skbs[txq->q.read_ptr] = NULL; + il->ops->txq_free_tfd(il, txq); } if (il_queue_space(q) > q->low_mark && txq_id >= 0 && @@ -336,7 +332,7 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) } txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); + info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]); ieee80211_tx_info_clear_status(info); /* Fill the MRR chain with some info about on-chip retransmissions */ @@ -577,8 +573,6 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel), rx_status.signal, rx_status.signal, rx_status.rate_idx); - il_dbg_log_rx_data_frame(il, le16_to_cpu(rx_hdr->len), header); - if (network_packet) { il->_3945.last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); @@ -660,15 +654,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq) PCI_DMA_TODEVICE); /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; + if (txq->skbs) { + struct sk_buff *skb = txq->skbs[txq->q.read_ptr]; /* can be called from irqs-disabled context */ if (skb) { dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; + txq->skbs[txq->q.read_ptr] = NULL; } } } @@ -798,7 +790,6 @@ il3945_rx_init(struct il_priv *il, struct il_rx_queue *rxq) static int il3945_tx_reset(struct il_priv *il) { - /* bypass mode */ il_wr_prph(il, ALM_SCD_MODE_REG, 0x2); @@ -835,8 +826,7 @@ il3945_tx_reset(struct il_priv *il) static int il3945_txq_ctx_reset(struct il_priv *il) { - int rc; - int txq_id, slots_num; + int rc, txq_id; il3945_hw_txq_ctx_free(il); @@ -852,10 +842,7 @@ il3945_txq_ctx_reset(struct il_priv *il) /* Tx queue(s) */ for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { - slots_num = - (txq_id == - IL39_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - rc = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id); + rc = il_tx_queue_init(il, txq_id); if (rc) { IL_ERR("Tx %d queue init failed\n", txq_id); goto error; @@ -960,12 +947,11 @@ il3945_hw_nic_init(struct il_priv *il) struct il_rx_queue *rxq = &il->rxq; spin_lock_irqsave(&il->lock, flags); - il->cfg->ops->lib->apm_ops.init(il); + il3945_apm_init(il); spin_unlock_irqrestore(&il->lock, flags); il3945_set_pwr_vmain(il); - - il->cfg->ops->lib->apm_ops.config(il); + il3945_nic_config(il); /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { @@ -1016,7 +1002,7 @@ il3945_hw_txq_ctx_free(struct il_priv *il) il_tx_queue_free(il, txq_id); /* free tx queue structure */ - il_txq_mem(il); + il_free_txq_mem(il); } void @@ -1025,18 +1011,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il) int txq_id; /* stop SCD */ - il_wr_prph(il, ALM_SCD_MODE_REG, 0); - il_wr_prph(il, ALM_SCD_TXFACT_REG, 0); + _il_wr_prph(il, ALM_SCD_MODE_REG, 0); + _il_wr_prph(il, ALM_SCD_TXFACT_REG, 0); /* reset TFD queues */ for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { - il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0); - il_poll_bit(il, FH39_TSSR_TX_STATUS, - FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), - 1000); + _il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0); + _il_poll_bit(il, FH39_TSSR_TX_STATUS, + FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), + FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), + 1000); } - - il3945_hw_txq_ctx_free(il); } /** @@ -1388,7 +1373,7 @@ il3945_send_tx_power(struct il_priv *il) int rate_idx, i; const struct il_channel_info *ch_info = NULL; struct il3945_txpowertable_cmd txpower = { - .channel = il->ctx.active.channel, + .channel = il->active.channel, }; u16 chan; @@ -1397,7 +1382,7 @@ il3945_send_tx_power(struct il_priv *il) "TX Power requested while scanning!\n")) return -EAGAIN; - chan = le16_to_cpu(il->ctx.active.channel); + chan = le16_to_cpu(il->active.channel); txpower.band = (il->band == IEEE80211_BAND_5GHZ) ? 0 : 1; ch_info = il_get_channel_info(il, il->band, chan); @@ -1615,7 +1600,7 @@ il3945_hw_reg_comp_txpower_temp(struct il_priv *il) } /* send Txpower command for current channel to ucode */ - return il->cfg->ops->lib->send_tx_power(il); + return il->ops->send_tx_power(il); } int @@ -1662,7 +1647,7 @@ il3945_hw_reg_set_txpower(struct il_priv *il, s8 power) } static int -il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) +il3945_send_rxon_assoc(struct il_priv *il) { int rc = 0; struct il_rx_pkt *pkt; @@ -1673,8 +1658,8 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) .flags = CMD_WANT_SKB, .data = &rxon_assoc, }; - const struct il_rxon_cmd *rxon1 = &ctx->staging; - const struct il_rxon_cmd *rxon2 = &ctx->active; + const struct il_rxon_cmd *rxon1 = &il->staging; + const struct il_rxon_cmd *rxon2 = &il->active; if (rxon1->flags == rxon2->flags && rxon1->filter_flags == rxon2->filter_flags && @@ -1684,10 +1669,10 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) return 0; } - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.flags = il->staging.flags; + rxon_assoc.filter_flags = il->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates; rxon_assoc.reserved = 0; rc = il_send_cmd_sync(il, &cmd); @@ -1714,11 +1699,11 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) * a HW tune is required based on the RXON structure changes. */ int -il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) +il3945_commit_rxon(struct il_priv *il) { /* cast away the const for active_rxon in this function */ - struct il3945_rxon_cmd *active_rxon = (void *)&ctx->active; - struct il3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; + struct il3945_rxon_cmd *active_rxon = (void *)&il->active; + struct il3945_rxon_cmd *staging_rxon = (void *)&il->staging; int rc = 0; bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); @@ -1735,7 +1720,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) staging_rxon->flags &= ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); staging_rxon->flags |= il3945_get_antenna_flags(il); - rc = il_check_rxon_cmd(il, ctx); + rc = il_check_rxon_cmd(il); if (rc) { IL_ERR("Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -1744,8 +1729,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) /* If we don't need to send a full RXON, we can use * il3945_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!il_full_rxon_required(il, &il->ctx)) { - rc = il_send_rxon_assoc(il, &il->ctx); + if (!il_full_rxon_required(il)) { + rc = il_send_rxon_assoc(il); if (rc) { IL_ERR("Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -1776,7 +1761,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) active_rxon->reserved4 = 0; active_rxon->reserved5 = 0; rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd), - &il->ctx.active); + &il->active); /* If the mask clearing failed then we set * active_rxon back to what it was previously */ @@ -1786,8 +1771,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) "configuration (%d).\n", rc); return rc; } - il_clear_ucode_stations(il, &il->ctx); - il_restore_stations(il, &il->ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); } D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" @@ -1801,7 +1786,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) staging_rxon->reserved4 = 0; staging_rxon->reserved5 = 0; - il_set_rxon_hwcrypto(il, ctx, !il3945_mod_params.sw_crypto); + il_set_rxon_hwcrypto(il, !il3945_mod_params.sw_crypto); /* Apply the new configuration */ rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd), @@ -1814,8 +1799,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); if (!new_assoc) { - il_clear_ucode_stations(il, &il->ctx); - il_restore_stations(il, &il->ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); } /* If we issue a new RXON command which required a tune then we must @@ -2186,12 +2171,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il) int il3945_hw_rxq_stop(struct il_priv *il) { - int rc; + int ret; - il_wr(il, FH39_RCSR_CONFIG(0), 0); - rc = il_poll_bit(il, FH39_RSSR_STATUS, - FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); - if (rc < 0) + _il_wr(il, FH39_RCSR_CONFIG(0), 0); + ret = _il_poll_bit(il, FH39_RSSR_STATUS, + FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, + FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, + 1000); + if (ret < 0) IL_ERR("Can't stop Rx DMA.\n"); return 0; @@ -2259,7 +2246,6 @@ il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data) static int il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r) { - struct il_rxon_context *ctx = &il->ctx; int ret; u8 sta_id; unsigned long flags; @@ -2267,7 +2253,7 @@ il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r) if (sta_id_r) *sta_id_r = IL_INVALID_STATION; - ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id); + ret = il_add_station_common(il, addr, 0, NULL, &sta_id); if (ret) { IL_ERR("Unable to add station %pM\n", addr); return ret; @@ -2397,15 +2383,16 @@ il3945_hw_set_hw_params(struct il_priv *il) return -ENOMEM; } + il->hw_params.bcast_id = IL3945_BROADCAST_ID; + /* Assign number of Usable TX queues */ - il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues; + il->hw_params.max_txq_num = il->cfg->num_of_queues; il->hw_params.tfd_size = sizeof(struct il3945_tfd); il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_3K); il->hw_params.max_rxq_size = RX_QUEUE_SIZE; il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; il->hw_params.max_stations = IL3945_STATION_COUNT; - il->ctx.bcast_sta_id = IL3945_BROADCAST_ID; il->sta_key_max_num = STA_KEY_MAX_NUM; @@ -2426,7 +2413,7 @@ il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame, tx_beacon_cmd = (struct il3945_tx_beacon_cmd *)&frame->u; memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); - tx_beacon_cmd->tx.sta_id = il->ctx.bcast_sta_id; + tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; frame_size = @@ -2633,76 +2620,31 @@ il3945_load_bsm(struct il_priv *il) return 0; } -static struct il_hcmd_ops il3945_hcmd = { - .rxon_assoc = il3945_send_rxon_assoc, - .commit_rxon = il3945_commit_rxon, -}; - -static struct il_lib_ops il3945_lib = { +const struct il_ops il3945_ops = { .txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd, .txq_free_tfd = il3945_hw_txq_free_tfd, .txq_init = il3945_hw_tx_queue_init, .load_ucode = il3945_load_bsm, .dump_nic_error_log = il3945_dump_nic_error_log, - .apm_ops = { - .init = il3945_apm_init, - .config = il3945_nic_config, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REGULATORY_BAND_1_CHANNELS, - EEPROM_REGULATORY_BAND_2_CHANNELS, - EEPROM_REGULATORY_BAND_3_CHANNELS, - EEPROM_REGULATORY_BAND_4_CHANNELS, - EEPROM_REGULATORY_BAND_5_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .acquire_semaphore = il3945_eeprom_acquire_semaphore, - .release_semaphore = il3945_eeprom_release_semaphore, - }, + .apm_init = il3945_apm_init, .send_tx_power = il3945_send_tx_power, .is_valid_rtc_data_addr = il3945_hw_valid_rtc_data_addr, + .eeprom_acquire_semaphore = il3945_eeprom_acquire_semaphore, + .eeprom_release_semaphore = il3945_eeprom_release_semaphore, -#ifdef CONFIG_IWLEGACY_DEBUGFS - .debugfs_ops = { - .rx_stats_read = il3945_ucode_rx_stats_read, - .tx_stats_read = il3945_ucode_tx_stats_read, - .general_stats_read = il3945_ucode_general_stats_read, - }, -#endif -}; - -static const struct il_legacy_ops il3945_legacy_ops = { - .post_associate = il3945_post_associate, - .config_ap = il3945_config_ap, - .manage_ibss_station = il3945_manage_ibss_station, -}; + .rxon_assoc = il3945_send_rxon_assoc, + .commit_rxon = il3945_commit_rxon, -static struct il_hcmd_utils_ops il3945_hcmd_utils = { .get_hcmd_size = il3945_get_hcmd_size, .build_addsta_hcmd = il3945_build_addsta_hcmd, .request_scan = il3945_request_scan, .post_scan = il3945_post_scan, -}; -static const struct il_ops il3945_ops = { - .lib = &il3945_lib, - .hcmd = &il3945_hcmd, - .utils = &il3945_hcmd_utils, - .led = &il3945_led_ops, - .legacy = &il3945_legacy_ops, - .ieee80211_ops = &il3945_hw_ops, -}; + .post_associate = il3945_post_associate, + .config_ap = il3945_config_ap, + .manage_ibss_station = il3945_manage_ibss_station, -static struct il_base_params il3945_base_params = { - .eeprom_size = IL3945_EEPROM_IMG_SIZE, - .num_of_queues = IL39_NUM_QUEUES, - .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, - .set_l0s = false, - .use_bsm = true, - .led_compensation = 64, - .wd_timeout = IL_DEF_WD_TIMEOUT, + .send_led_cmd = il3945_send_led_cmd, }; static struct il_cfg il3945_bg_cfg = { @@ -2712,10 +2654,26 @@ static struct il_cfg il3945_bg_cfg = { .ucode_api_min = IL3945_UCODE_API_MIN, .sku = IL_SKU_G, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &il3945_ops, .mod_params = &il3945_mod_params, - .base_params = &il3945_base_params, .led_mode = IL_LED_BLINK, + + .eeprom_size = IL3945_EEPROM_IMG_SIZE, + .num_of_queues = IL39_NUM_QUEUES, + .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, + .set_l0s = false, + .use_bsm = true, + .led_compensation = 64, + .wd_timeout = IL_DEF_WD_TIMEOUT, + + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + EEPROM_REGULATORY_BAND_NO_HT40, + }, }; static struct il_cfg il3945_abg_cfg = { @@ -2725,10 +2683,26 @@ static struct il_cfg il3945_abg_cfg = { .ucode_api_min = IL3945_UCODE_API_MIN, .sku = IL_SKU_A | IL_SKU_G, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &il3945_ops, .mod_params = &il3945_mod_params, - .base_params = &il3945_base_params, .led_mode = IL_LED_BLINK, + + .eeprom_size = IL3945_EEPROM_IMG_SIZE, + .num_of_queues = IL39_NUM_QUEUES, + .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, + .set_l0s = false, + .use_bsm = true, + .led_compensation = 64, + .wd_timeout = IL_DEF_WD_TIMEOUT, + + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + EEPROM_REGULATORY_BAND_NO_HT40, + }, }; DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = { diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 9f42f79f877..1d45075e0d5 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -36,6 +36,8 @@ extern const struct pci_device_id il3945_hw_card_ids[]; #include "common.h" +extern const struct il_ops il3945_ops; + /* Highest firmware API version supported */ #define IL3945_UCODE_API_MAX 2 @@ -249,7 +251,7 @@ extern int il4965_get_temperature(const struct il_priv *il); extern void il3945_post_associate(struct il_priv *il); extern void il3945_config_ap(struct il_priv *il); -extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx); +extern int il3945_commit_rxon(struct il_priv *il); /** * il3945_hw_find_station - Find station id for a given BSSID @@ -261,8 +263,6 @@ extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx); */ extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid); -extern struct ieee80211_ops il3945_hw_ops; - extern __le32 il3945_get_antenna_flags(const struct il_priv *il); extern int il3945_init_hw_rate_table(struct il_priv *il); extern void il3945_reg_txpower_periodic(struct il_priv *il); @@ -595,13 +595,7 @@ struct il3945_tfd { } __packed; #ifdef CONFIG_IWLEGACY_DEBUGFS -ssize_t il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t il3945_ucode_general_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos); +extern const struct il_debugfs_ops il3945_debugfs_ops; #endif #endif diff --git a/drivers/net/wireless/iwlegacy/4965-calib.c b/drivers/net/wireless/iwlegacy/4965-calib.c index d3248e3ef23..e78bdefb895 100644 --- a/drivers/net/wireless/iwlegacy/4965-calib.c +++ b/drivers/net/wireless/iwlegacy/4965-calib.c @@ -79,18 +79,6 @@ struct stats_general_data { u32 beacon_energy_c; }; -void -il4965_calib_free_results(struct il_priv *il) -{ - int i; - - for (i = 0; i < IL_CALIB_MAX; i++) { - kfree(il->calib_results[i].buf); - il->calib_results[i].buf = NULL; - il->calib_results[i].buf_len = 0; - } -} - /***************************************************************************** * RUNTIME calibrations framework *****************************************************************************/ @@ -627,13 +615,13 @@ il4965_find_disconn_antenna(struct il_priv *il, u32 * average_sig, average_sig[0] = data->chain_signal_a / - il->cfg->base_params->chain_noise_num_beacons; + il->cfg->chain_noise_num_beacons; average_sig[1] = data->chain_signal_b / - il->cfg->base_params->chain_noise_num_beacons; + il->cfg->chain_noise_num_beacons; average_sig[2] = data->chain_signal_c / - il->cfg->base_params->chain_noise_num_beacons; + il->cfg->chain_noise_num_beacons; if (average_sig[0] >= average_sig[1]) { max_average_sig = average_sig[0]; @@ -806,8 +794,6 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) unsigned long flags; struct stats_rx_non_phy *rx_info; - struct il_rxon_context *ctx = &il->ctx; - if (il->disable_chain_noise_cal) return; @@ -833,8 +819,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) return; } - rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); - rxon_chnum = le16_to_cpu(ctx->staging.channel); + rxon_band24 = !!(il->staging.flags & RXON_FLG_BAND_24G_MSK); + rxon_chnum = le16_to_cpu(il->staging.channel); stat_band24 = !!(((struct il_notif_stats *)stat_resp)-> @@ -888,7 +874,7 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) /* If this is the "chain_noise_num_beacons", determine: * 1) Disconnected antennas (using signal strengths) * 2) Differential gain (using silence noise) to balance receivers */ - if (data->beacon_count != il->cfg->base_params->chain_noise_num_beacons) + if (data->beacon_count != il->cfg->chain_noise_num_beacons) return; /* Analyze signal for disconnected antenna */ @@ -896,11 +882,11 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) /* Analyze noise for rx balance */ average_noise[0] = - data->chain_noise_a / il->cfg->base_params->chain_noise_num_beacons; + data->chain_noise_a / il->cfg->chain_noise_num_beacons; average_noise[1] = - data->chain_noise_b / il->cfg->base_params->chain_noise_num_beacons; + data->chain_noise_b / il->cfg->chain_noise_num_beacons; average_noise[2] = - data->chain_noise_c / il->cfg->base_params->chain_noise_num_beacons; + data->chain_noise_c / il->cfg->chain_noise_num_beacons; for (i = 0; i < NUM_RX_CHAINS; i++) { if (!data->disconn_array[i] && @@ -925,8 +911,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp) /* Some power changes may have been made during the calibration. * Update and commit the RXON */ - if (il->cfg->ops->lib->update_chain_flags) - il->cfg->ops->lib->update_chain_flags(il); + if (il->ops->update_chain_flags) + il->ops->update_chain_flags(il); data->state = IL_CHAIN_NOISE_DONE; il_power_update_mode(il, false); diff --git a/drivers/net/wireless/iwlegacy/4965-debug.c b/drivers/net/wireless/iwlegacy/4965-debug.c index 98ec39f56ba..c8153fc64f7 100644 --- a/drivers/net/wireless/iwlegacy/4965-debug.c +++ b/drivers/net/wireless/iwlegacy/4965-debug.c @@ -744,3 +744,9 @@ il4965_ucode_general_stats_read(struct file *file, char __user *user_buf, kfree(buf); return ret; } + +const struct il_debugfs_ops il4965_debugfs_ops = { + .rx_stats_read = il4965_ucode_rx_stats_read, + .tx_stats_read = il4965_ucode_tx_stats_read, + .general_stats_read = il4965_ucode_general_stats_read, +}; diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 1667232af64..7b54dbb338b 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -199,18 +199,14 @@ il4965_hw_nic_init(struct il_priv *il) struct il_rx_queue *rxq = &il->rxq; int ret; - /* nic_init */ spin_lock_irqsave(&il->lock, flags); - il->cfg->ops->lib->apm_ops.init(il); - + il_apm_init(il); /* Set interrupt coalescing calibration timer to default (512 usecs) */ il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF); - spin_unlock_irqrestore(&il->lock, flags); il4965_set_pwr_vmain(il); - - il->cfg->ops->lib->apm_ops.config(il); + il4965_nic_config(il); /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { @@ -445,11 +441,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq) int il4965_rxq_stop(struct il_priv *il) { + int ret; - /* stop Rx DMA */ - il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0); - il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG, - FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); + _il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0); + ret = _il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG, + FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, + FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, + 1000); + if (ret < 0) + IL_ERR("Can't stop Rx DMA.\n"); return 0; } @@ -692,7 +692,6 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) /* Find max signal strength (dBm) among 3 antenna/receiver chains */ rx_status.signal = il4965_calc_rssi(il, phy_res); - il_dbg_log_rx_data_frame(il, len, header); D_STATS("Rssi %d, TSF %llu\n", rx_status.signal, (unsigned long long)rx_status.mactime); @@ -843,7 +842,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) .flags = CMD_SIZE_HUGE, }; struct il_scan_cmd *scan; - struct il_rxon_context *ctx = &il->ctx; u32 rate_flags = 0; u16 cmd_len; u16 rx_chain = 0; @@ -859,8 +857,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) lockdep_assert_held(&il->mutex); - ctx = il_rxon_ctx_from_vif(vif); - if (!il->scan_cmd) { il->scan_cmd = kmalloc(sizeof(struct il_scan_cmd) + IL_MAX_SCAN_SIZE, @@ -919,15 +915,14 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif) D_SCAN("Start passive scan.\n"); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = ctx->bcast_sta_id; + scan->tx_cmd.sta_id = il->hw_params.bcast_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; switch (il->scan_band) { case IEEE80211_BAND_2GHZ: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; chan_mod = - le32_to_cpu(il->ctx.active. - flags & RXON_FLG_CHANNEL_MODE_MSK) >> + le32_to_cpu(il->active.flags & RXON_FLG_CHANNEL_MODE_MSK) >> RXON_FLG_CHANNEL_MODE_POS; if (chan_mod == CHANNEL_MODE_PURE_40) { rate = RATE_6M_PLCP; @@ -1034,8 +1029,7 @@ il4965_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif, struct il_vif_priv *vif_priv = (void *)vif->drv_priv; if (add) - return il4965_add_bssid_station(il, vif_priv->ctx, - vif->bss_conf.bssid, + return il4965_add_bssid_station(il, vif->bss_conf.bssid, &vif_priv->ibss_bssid_sta_id); return il_remove_station(il, vif_priv->ibss_bssid_sta_id, vif->bss_conf.bssid); @@ -1128,7 +1122,7 @@ il4965_count_chain_bitmap(u32 chain_bitmap) * This should not be used for scan command ... it puts data in wrong place. */ void -il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx) +il4965_set_rxon_chain(struct il_priv *il) { bool is_single = il4965_is_single_rx_stream(il); bool is_cam = !test_bit(S_POWER_PMI, &il->status); @@ -1164,14 +1158,14 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx) rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; - ctx->staging.rx_chain = cpu_to_le16(rx_chain); + il->staging.rx_chain = cpu_to_le16(rx_chain); if (!is_single && active_rx_cnt >= IL_NUM_RX_CHAINS_SINGLE && is_cam) - ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; + il->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; else - ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + il->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; - D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", ctx->staging.rx_chain, + D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", il->staging.rx_chain, active_rx_cnt, idle_rx_cnt); WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || @@ -1348,12 +1342,11 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats) } #endif -#define REG_RECALIB_PERIOD (60) - void il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) { - int change; + const int recalib_seconds = 60; + bool change; struct il_rx_pkt *pkt = rxb_addr(rxb); D_RX("Statistics notification received (%d vs %d).\n", @@ -1374,20 +1367,21 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb) set_bit(S_STATS, &il->status); - /* Reschedule the stats timer to occur in - * REG_RECALIB_PERIOD seconds to ensure we get a - * thermal update even if the uCode doesn't give - * us one */ + /* + * Reschedule the stats timer to occur in recalib_seconds to ensure + * we get a thermal update even if the uCode doesn't give us one + */ mod_timer(&il->stats_periodic, - jiffies + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000)); + jiffies + msecs_to_jiffies(recalib_seconds * 1000)); if (unlikely(!test_bit(S_SCANNING, &il->status)) && (pkt->hdr.cmd == N_STATS)) { il4965_rx_calc_noise(il); queue_work(il->workqueue, &il->run_time_calib_work); } - if (il->cfg->ops->lib->temp_ops.temperature && change) - il->cfg->ops->lib->temp_ops.temperature(il); + + if (change) + il4965_temperature_calib(il); } void @@ -1457,10 +1451,17 @@ il4965_get_ac_from_tid(u16 tid) } static inline int -il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid) +il4965_get_fifo_from_tid(u16 tid) { + const u8 ac_to_fifo[] = { + IL_TX_FIFO_VO, + IL_TX_FIFO_VI, + IL_TX_FIFO_BE, + IL_TX_FIFO_BK, + }; + if (likely(tid < ARRAY_SIZE(tid_to_ac))) - return ctx->ac_to_fifo[tid_to_ac[tid]]; + return ac_to_fifo[tid_to_ac[tid]]; /* no support for TIDs 8-15 yet */ return -EINVAL; @@ -1639,7 +1640,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) struct il_device_cmd *out_cmd; struct il_cmd_meta *out_meta; struct il_tx_cmd *tx_cmd; - struct il_rxon_context *ctx = &il->ctx; int txq_id; dma_addr_t phys_addr; dma_addr_t txcmd_phys; @@ -1655,9 +1655,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) unsigned long flags; bool is_agg = false; - if (info->control.vif) - ctx = il_rxon_ctx_from_vif(info->control.vif); - spin_lock_irqsave(&il->lock, flags); if (il_is_rfkill(il)) { D_DROP("Dropping - RF KILL\n"); @@ -1679,10 +1676,10 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* For management frames use broadcast id to do not break aggregation */ if (!ieee80211_is_data(fc)) - sta_id = ctx->bcast_sta_id; + sta_id = il->hw_params.bcast_id; else { /* Find idx into station table for destination station */ - sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta); + sta_id = il_sta_id_or_broadcast(il, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -1696,7 +1693,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) sta_priv = (void *)sta->drv_priv; if (sta_priv && sta_priv->asleep && - (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) { + (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) { /* * This sends an asynchronous command to the device, * but we can rely on it being processed before the @@ -1709,19 +1706,11 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) il4965_sta_modify_sleep_tx_count(il, sta_id, 1); } - /* - * Send this frame after DTIM -- there's a special queue - * reserved for this for contexts that support AP mode. - */ - if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { - txq_id = ctx->mcast_queue; - /* - * The microcode will clear the more data - * bit in the last frame it transmits. - */ - hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); - } else - txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; + /* FIXME: remove me ? */ + WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); + + /* Access category (AC) is also the queue number */ + txq_id = skb_get_queue_mapping(skb); /* irqs already disabled/saved above when locking il->lock */ spin_lock(&il->sta_lock); @@ -1763,10 +1752,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) spin_unlock(&il->sta_lock); - /* Set up driver data for this TFD */ - memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info)); - txq->txb[q->write_ptr].skb = skb; - txq->txb[q->write_ptr].ctx = ctx; + txq->skbs[q->write_ptr] = skb; /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[q->write_ptr]; @@ -1798,7 +1784,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* TODO need this for burst mode later on */ il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id); - il_dbg_log_tx_data_frame(il, len, hdr); il4965_tx_cmd_build_rate(il, tx_cmd, info, fc); @@ -1828,8 +1813,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) dma_unmap_len_set(out_meta, len, firstlen); /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, - 1, 0); + il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; @@ -1845,8 +1829,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) phys_addr = pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, PCI_DMA_TODEVICE); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, - secondlen, 0, 0); + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, + 0, 0); } scratch_phys = @@ -1866,9 +1850,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* Set up entry for this TFD in Tx byte-count array */ if (info->flags & IEEE80211_TX_CTL_AMPDU) - il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, - le16_to_cpu(tx_cmd-> - len)); + il->ops->txq_update_byte_cnt_tbl(il, txq, le16_to_cpu(tx_cmd->len)); pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen, PCI_DMA_BIDIRECTIONAL); @@ -1957,7 +1939,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il) il4965_free_dma_ptr(il, &il->scd_bc_tbls); /* free tx queue structure */ - il_txq_mem(il); + il_free_txq_mem(il); } /** @@ -1970,8 +1952,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il) int il4965_txq_ctx_alloc(struct il_priv *il) { - int ret; - int txq_id, slots_num; + int ret, txq_id; unsigned long flags; /* Free all tx/cmd queues and keep-warm buffer */ @@ -2008,10 +1989,7 @@ il4965_txq_ctx_alloc(struct il_priv *il) /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { - slots_num = - (txq_id == - il->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - ret = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id); + ret = il_tx_queue_init(il, txq_id); if (ret) { IL_ERR("Tx %d queue init failed\n", txq_id); goto error; @@ -2032,52 +2010,27 @@ error_bc_tbls: void il4965_txq_ctx_reset(struct il_priv *il) { - int txq_id, slots_num; + int txq_id; unsigned long flags; spin_lock_irqsave(&il->lock, flags); /* Turn off all Tx DMA fifos */ il4965_txq_set_sched(il, 0); - /* Tell NIC where to find the "keep warm" buffer */ il_wr(il, FH49_KW_MEM_ADDR_REG, il->kw.dma >> 4); spin_unlock_irqrestore(&il->lock, flags); /* Alloc and init all Tx queues, including the command queue (#4) */ - for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) { - slots_num = - txq_id == il->cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - il_tx_queue_reset(il, &il->txq[txq_id], slots_num, txq_id); - } + for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) + il_tx_queue_reset(il, txq_id); } -/** - * il4965_txq_ctx_stop - Stop all Tx DMA channels - */ void -il4965_txq_ctx_stop(struct il_priv *il) +il4965_txq_ctx_unmap(struct il_priv *il) { - int ch, txq_id; - unsigned long flags; - - /* Turn off all Tx DMA fifos */ - spin_lock_irqsave(&il->lock, flags); - - il4965_txq_set_sched(il, 0); - - /* Stop each Tx DMA channel, and wait for it to be idle */ - for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) { - il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - if (il_poll_bit - (il, FH49_TSSR_TX_STATUS_REG, - FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000)) - IL_ERR("Failing on timeout while stopping" - " DMA channel %d [0x%08x]", ch, - il_rd(il, FH49_TSSR_TX_STATUS_REG)); - } - spin_unlock_irqrestore(&il->lock, flags); + int txq_id; if (!il->txq) return; @@ -2090,6 +2043,30 @@ il4965_txq_ctx_stop(struct il_priv *il) il_tx_queue_unmap(il, txq_id); } +/** + * il4965_txq_ctx_stop - Stop all Tx DMA channels + */ +void +il4965_txq_ctx_stop(struct il_priv *il) +{ + int ch, ret; + + _il_wr_prph(il, IL49_SCD_TXFACT, 0); + + /* Stop each Tx DMA channel, and wait for it to be idle */ + for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) { + _il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); + ret = + _il_poll_bit(il, FH49_TSSR_TX_STATUS_REG, + FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), + FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), + 1000); + if (ret < 0) + IL_ERR("Timeout stopping DMA channel %d [0x%08x]", + ch, _il_rd(il, FH49_TSSR_TX_STATUS_REG)); + } +} + /* * Find first available (lowest unused) Tx Queue, mark it "active". * Called only when finding queue for aggregation. @@ -2163,11 +2140,11 @@ il4965_txq_agg_enable(struct il_priv *il, int txq_id, int tx_fifo, int sta_id, if ((IL49_FIRST_AMPDU_QUEUE > txq_id) || (IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + il->cfg->num_of_ampdu_queues <= txq_id)) { IL_WARN("queue number out of range: %d, must be %d to %d\n", txq_id, IL49_FIRST_AMPDU_QUEUE, IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues - 1); + il->cfg->num_of_ampdu_queues - 1); return -EINVAL; } @@ -2230,7 +2207,8 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif, unsigned long flags; struct il_tid_data *tid_data; - tx_fifo = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid); + /* FIXME: warning if tx fifo not found ? */ + tx_fifo = il4965_get_fifo_from_tid(tid); if (unlikely(tx_fifo < 0)) return tx_fifo; @@ -2290,11 +2268,11 @@ il4965_txq_agg_disable(struct il_priv *il, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { if ((IL49_FIRST_AMPDU_QUEUE > txq_id) || (IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues <= txq_id)) { + il->cfg->num_of_ampdu_queues <= txq_id)) { IL_WARN("queue number out of range: %d, must be %d to %d\n", txq_id, IL49_FIRST_AMPDU_QUEUE, IL49_FIRST_AMPDU_QUEUE + - il->cfg->base_params->num_of_ampdu_queues - 1); + il->cfg->num_of_ampdu_queues - 1); return -EINVAL; } @@ -2323,7 +2301,8 @@ il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif, int write_ptr, read_ptr; unsigned long flags; - tx_fifo_id = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid); + /* FIXME: warning if tx_fifo_id not found ? */ + tx_fifo_id = il4965_get_fifo_from_tid(tid); if (unlikely(tx_fifo_id < 0)) return tx_fifo_id; @@ -2397,9 +2376,6 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) struct il_queue *q = &il->txq[txq_id].q; u8 *addr = il->stations[sta_id].sta.sta.addr; struct il_tid_data *tid_data = &il->stations[sta_id].tid[tid]; - struct il_rxon_context *ctx; - - ctx = &il->ctx; lockdep_assert_held(&il->sta_lock); @@ -2410,11 +2386,11 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) if (txq_id == tid_data->agg.txq_id && q->read_ptr == q->write_ptr) { u16 ssn = SEQ_TO_SN(tid_data->seq_number); - int tx_fifo = il4965_get_fifo_from_tid(ctx, tid); + int tx_fifo = il4965_get_fifo_from_tid(tid); D_HT("HW queue empty: continue DELBA flow\n"); il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo); tid_data->agg.state = IL_AGG_OFF; - ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); + ieee80211_stop_tx_ba_cb_irqsafe(il->vif, addr, tid); } break; case IL_EMPTYING_HW_QUEUE_ADDBA: @@ -2422,7 +2398,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) if (tid_data->tfds_in_queue == 0) { D_HT("HW queue empty: continue ADDBA flow\n"); tid_data->agg.state = IL_AGG_ON; - ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid); + ieee80211_start_tx_ba_cb_irqsafe(il->vif, addr, tid); } break; } @@ -2431,14 +2407,13 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) } static void -il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr1) +il4965_non_agg_tx_status(struct il_priv *il, const u8 *addr1) { struct ieee80211_sta *sta; struct il_station_priv *sta_priv; rcu_read_lock(); - sta = ieee80211_find_sta(ctx->vif, addr1); + sta = ieee80211_find_sta(il->vif, addr1); if (sta) { sta_priv = (void *)sta->drv_priv; /* avoid atomic ops if this isn't a client */ @@ -2450,14 +2425,14 @@ il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx, } static void -il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info, bool is_agg) +il4965_tx_status(struct il_priv *il, struct sk_buff *skb, bool is_agg) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; if (!is_agg) - il4965_non_agg_tx_status(il, tx_info->ctx, hdr->addr1); + il4965_non_agg_tx_status(il, hdr->addr1); - ieee80211_tx_status_irqsafe(il->hw, tx_info->skb); + ieee80211_tx_status_irqsafe(il->hw, skb); } int @@ -2465,9 +2440,9 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) { struct il_tx_queue *txq = &il->txq[txq_id]; struct il_queue *q = &txq->q; - struct il_tx_info *tx_info; int nfreed = 0; struct ieee80211_hdr *hdr; + struct sk_buff *skb; if (idx >= q->n_bd || il_queue_used(q, idx) == 0) { IL_ERR("Read idx for DMA queue txq id (%d), idx %d, " @@ -2479,20 +2454,19 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx) for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) { - tx_info = &txq->txb[txq->q.read_ptr]; + skb = txq->skbs[txq->q.read_ptr]; - if (WARN_ON_ONCE(tx_info->skb == NULL)) + if (WARN_ON_ONCE(skb == NULL)) continue; - hdr = (struct ieee80211_hdr *)tx_info->skb->data; + hdr = (struct ieee80211_hdr *) skb->data; if (ieee80211_is_data_qos(hdr->frame_control)) nfreed++; - il4965_tx_status(il, tx_info, - txq_id >= IL4965_FIRST_AMPDU_QUEUE); - tx_info->skb = NULL; + il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE); - il->cfg->ops->lib->txq_free_tfd(il, txq); + txq->skbs[txq->q.read_ptr] = NULL; + il->ops->txq_free_tfd(il, txq); } return nfreed; } @@ -2555,7 +2529,7 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg, D_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); - info = IEEE80211_SKB_CB(il->txq[scd_flow].txb[agg->start_idx].skb); + info = IEEE80211_SKB_CB(il->txq[scd_flow].skbs[agg->start_idx]); memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_AMPDU; @@ -2566,6 +2540,308 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg, return 0; } +static inline bool +il4965_is_tx_success(u32 status) +{ + status &= TX_STATUS_MSK; + return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE); +} + +static u8 +il4965_find_station(struct il_priv *il, const u8 *addr) +{ + int i; + int start = 0; + int ret = IL_INVALID_STATION; + unsigned long flags; + + if (il->iw_mode == NL80211_IFTYPE_ADHOC) + start = IL_STA_ID; + + if (is_broadcast_ether_addr(addr)) + return il->hw_params.bcast_id; + + spin_lock_irqsave(&il->sta_lock, flags); + for (i = start; i < il->hw_params.max_stations; i++) + if (il->stations[i].used && + (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) { + ret = i; + goto out; + } + + D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations); + +out: + /* + * It may be possible that more commands interacting with stations + * arrive before we completed processing the adding of + * station + */ + if (ret != IL_INVALID_STATION && + (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) || + ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) && + (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) { + IL_ERR("Requested station info for sta %d before ready.\n", + ret); + ret = IL_INVALID_STATION; + } + spin_unlock_irqrestore(&il->sta_lock, flags); + return ret; +} + +static int +il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr) +{ + if (il->iw_mode == NL80211_IFTYPE_STATION) + return IL_AP_ID; + else { + u8 *da = ieee80211_get_DA(hdr); + + return il4965_find_station(il, da); + } +} + +static inline u32 +il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp) +{ + return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; +} + +static inline u32 +il4965_tx_status_to_mac80211(u32 status) +{ + status &= TX_STATUS_MSK; + + switch (status) { + case TX_STATUS_SUCCESS: + case TX_STATUS_DIRECT_DONE: + return IEEE80211_TX_STAT_ACK; + case TX_STATUS_FAIL_DEST_PS: + return IEEE80211_TX_STAT_TX_FILTERED; + default: + return 0; + } +} + +/** + * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue + */ +static int +il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, + struct il4965_tx_resp *tx_resp, int txq_id, + u16 start_idx) +{ + u16 status; + struct agg_tx_status *frame_status = tx_resp->u.agg_status; + struct ieee80211_tx_info *info = NULL; + struct ieee80211_hdr *hdr = NULL; + u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); + int i, sh, idx; + u16 seq; + if (agg->wait_for_ba) + D_TX_REPLY("got tx response w/o block-ack\n"); + + agg->frame_count = tx_resp->frame_count; + agg->start_idx = start_idx; + agg->rate_n_flags = rate_n_flags; + agg->bitmap = 0; + + /* num frames attempted by Tx command */ + if (agg->frame_count == 1) { + /* Only one frame was attempted; no block-ack will arrive */ + status = le16_to_cpu(frame_status[0].status); + idx = start_idx; + + D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", + agg->frame_count, agg->start_idx, idx); + + info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]); + info->status.rates[0].count = tx_resp->failure_frame + 1; + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + info->flags |= il4965_tx_status_to_mac80211(status); + il4965_hwrate_to_tx_control(il, rate_n_flags, info); + + D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff, + tx_resp->failure_frame); + D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); + + agg->wait_for_ba = 0; + } else { + /* Two or more frames were attempted; expect block-ack */ + u64 bitmap = 0; + int start = agg->start_idx; + struct sk_buff *skb; + + /* Construct bit-map of pending frames within Tx win */ + for (i = 0; i < agg->frame_count; i++) { + u16 sc; + status = le16_to_cpu(frame_status[i].status); + seq = le16_to_cpu(frame_status[i].sequence); + idx = SEQ_TO_IDX(seq); + txq_id = SEQ_TO_QUEUE(seq); + + if (status & + (AGG_TX_STATE_FEW_BYTES_MSK | + AGG_TX_STATE_ABORT_MSK)) + continue; + + D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n", + agg->frame_count, txq_id, idx); + + skb = il->txq[txq_id].skbs[idx]; + if (WARN_ON_ONCE(skb == NULL)) + return -1; + hdr = (struct ieee80211_hdr *) skb->data; + + sc = le16_to_cpu(hdr->seq_ctrl); + if (idx != (SEQ_TO_SN(sc) & 0xff)) { + IL_ERR("BUG_ON idx doesn't match seq control" + " idx=%d, seq_idx=%d, seq=%d\n", idx, + SEQ_TO_SN(sc), hdr->seq_ctrl); + return -1; + } + + D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx, + SEQ_TO_SN(sc)); + + sh = idx - start; + if (sh > 64) { + sh = (start - idx) + 0xff; + bitmap = bitmap << sh; + sh = 0; + start = idx; + } else if (sh < -64) + sh = 0xff - (start - idx); + else if (sh < 0) { + sh = start - idx; + start = idx; + bitmap = bitmap << sh; + sh = 0; + } + bitmap |= 1ULL << sh; + D_TX_REPLY("start=%d bitmap=0x%llx\n", start, + (unsigned long long)bitmap); + } + + agg->bitmap = bitmap; + agg->start_idx = start; + D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", + agg->frame_count, agg->start_idx, + (unsigned long long)agg->bitmap); + + if (bitmap) + agg->wait_for_ba = 1; + } + return 0; +} + +/** + * il4965_hdl_tx - Handle standard (non-aggregation) Tx response + */ +static void +il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) +{ + struct il_rx_pkt *pkt = rxb_addr(rxb); + u16 sequence = le16_to_cpu(pkt->hdr.sequence); + int txq_id = SEQ_TO_QUEUE(sequence); + int idx = SEQ_TO_IDX(sequence); + struct il_tx_queue *txq = &il->txq[txq_id]; + struct sk_buff *skb; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info; + struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + u32 status = le32_to_cpu(tx_resp->u.status); + int uninitialized_var(tid); + int sta_id; + int freed; + u8 *qc = NULL; + unsigned long flags; + + if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) { + IL_ERR("Read idx for DMA queue txq_id (%d) idx %d " + "is out of range [0-%d] %d %d\n", txq_id, idx, + txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr); + return; + } + + txq->time_stamp = jiffies; + + skb = txq->skbs[txq->q.read_ptr]; + info = IEEE80211_SKB_CB(skb); + memset(&info->status, 0, sizeof(info->status)); + + hdr = (struct ieee80211_hdr *) skb->data; + if (ieee80211_is_data_qos(hdr->frame_control)) { + qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & 0xf; + } + + sta_id = il4965_get_ra_sta_id(il, hdr); + if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) { + IL_ERR("Station not known\n"); + return; + } + + spin_lock_irqsave(&il->sta_lock, flags); + if (txq->sched_retry) { + const u32 scd_ssn = il4965_get_scd_ssn(tx_resp); + struct il_ht_agg *agg = NULL; + WARN_ON(!qc); + + agg = &il->stations[sta_id].tid[tid].agg; + + il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx); + + /* check if BAR is needed */ + if (tx_resp->frame_count == 1 && + !il4965_is_tx_success(status)) + info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + + if (txq->q.read_ptr != (scd_ssn & 0xff)) { + idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); + D_TX_REPLY("Retry scheduler reclaim scd_ssn " + "%d idx %d\n", scd_ssn, idx); + freed = il4965_tx_queue_reclaim(il, txq_id, idx); + if (qc) + il4965_free_tfds_in_queue(il, sta_id, tid, + freed); + + if (il->mac80211_registered && + il_queue_space(&txq->q) > txq->q.low_mark && + agg->state != IL_EMPTYING_HW_QUEUE_DELBA) + il_wake_queue(il, txq); + } + } else { + info->status.rates[0].count = tx_resp->failure_frame + 1; + info->flags |= il4965_tx_status_to_mac80211(status); + il4965_hwrate_to_tx_control(il, + le32_to_cpu(tx_resp->rate_n_flags), + info); + + D_TX_REPLY("TXQ %d status %s (0x%08x) " + "rate_n_flags 0x%x retries %d\n", txq_id, + il4965_get_tx_fail_reason(status), status, + le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); + + freed = il4965_tx_queue_reclaim(il, txq_id, idx); + if (qc && likely(sta_id != IL_INVALID_STATION)) + il4965_free_tfds_in_queue(il, sta_id, tid, freed); + else if (sta_id == IL_INVALID_STATION) + D_TX_REPLY("Station not known\n"); + + if (il->mac80211_registered && + il_queue_space(&txq->q) > txq->q.low_mark) + il_wake_queue(il, txq); + } + if (qc && likely(sta_id != IL_INVALID_STATION)) + il4965_txq_check_empty(il, sta_id, tid, txq_id); + + il4965_check_abort_status(il, tx_resp->frame_count, status); + + spin_unlock_irqrestore(&il->sta_lock, flags); +} + /** * translate ucode response to mac80211 tx status control values */ @@ -2771,8 +3047,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id) * Function sleeps. */ int -il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, u8 *sta_id_r) +il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r) { int ret; u8 sta_id; @@ -2782,7 +3057,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, if (sta_id_r) *sta_id_r = IL_INVALID_STATION; - ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id); + ret = il_add_station_common(il, addr, 0, NULL, &sta_id); if (ret) { IL_ERR("Unable to add station %pM\n", addr); return ret; @@ -2803,7 +3078,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, return -ENOMEM; } - ret = il_send_lq_cmd(il, ctx, link_cmd, CMD_SYNC, true); + ret = il_send_lq_cmd(il, link_cmd, CMD_SYNC, true); if (ret) IL_ERR("Link quality command failed (%d)\n", ret); @@ -2815,19 +3090,19 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, } static int -il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, - bool send_if_empty) +il4965_static_wepkey_cmd(struct il_priv *il, bool send_if_empty) { - int i, not_empty = 0; + int i; u8 buff[sizeof(struct il_wep_cmd) + sizeof(struct il_wep_key) * WEP_KEYS_MAX]; struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff; size_t cmd_size = sizeof(struct il_wep_cmd); struct il_host_cmd cmd = { - .id = ctx->wep_key_cmd, + .id = C_WEPKEY, .data = wep_cmd, .flags = CMD_SYNC, }; + bool not_empty = false; might_sleep(); @@ -2835,24 +3110,23 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, cmd_size + (sizeof(struct il_wep_key) * WEP_KEYS_MAX)); for (i = 0; i < WEP_KEYS_MAX; i++) { + u8 key_size = il->_4965.wep_keys[i].key_size; + wep_cmd->key[i].key_idx = i; - if (ctx->wep_keys[i].key_size) { + if (key_size) { wep_cmd->key[i].key_offset = i; - not_empty = 1; - } else { + not_empty = true; + } else wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; - } - wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; - memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, - ctx->wep_keys[i].key_size); + wep_cmd->key[i].key_size = key_size; + memcpy(&wep_cmd->key[i].key[3], il->_4965.wep_keys[i].key, key_size); } wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; wep_cmd->num_keys = WEP_KEYS_MAX; cmd_size += sizeof(struct il_wep_key) * WEP_KEYS_MAX; - cmd.len = cmd_size; if (not_empty || send_if_empty) @@ -2862,66 +3136,66 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx, } int -il4965_restore_default_wep_keys(struct il_priv *il, struct il_rxon_context *ctx) +il4965_restore_default_wep_keys(struct il_priv *il) { lockdep_assert_held(&il->mutex); - return il4965_static_wepkey_cmd(il, ctx, false); + return il4965_static_wepkey_cmd(il, false); } int -il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, +il4965_remove_default_wep_key(struct il_priv *il, struct ieee80211_key_conf *keyconf) { int ret; + int idx = keyconf->keyidx; lockdep_assert_held(&il->mutex); - D_WEP("Removing default WEP key: idx=%d\n", keyconf->keyidx); + D_WEP("Removing default WEP key: idx=%d\n", idx); - memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); + memset(&il->_4965.wep_keys[idx], 0, sizeof(struct il_wep_key)); if (il_is_rfkill(il)) { D_WEP("Not sending C_WEPKEY command due to RFKILL.\n"); /* but keys in device are clear anyway so return success */ return 0; } - ret = il4965_static_wepkey_cmd(il, ctx, 1); - D_WEP("Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret); + ret = il4965_static_wepkey_cmd(il, 1); + D_WEP("Remove default WEP key: idx=%d ret=%d\n", idx, ret); return ret; } int -il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, +il4965_set_default_wep_key(struct il_priv *il, struct ieee80211_key_conf *keyconf) { int ret; + int len = keyconf->keylen; + int idx = keyconf->keyidx; lockdep_assert_held(&il->mutex); - if (keyconf->keylen != WEP_KEY_LEN_128 && - keyconf->keylen != WEP_KEY_LEN_64) { + if (len != WEP_KEY_LEN_128 && len != WEP_KEY_LEN_64) { D_WEP("Bad WEP key length %d\n", keyconf->keylen); return -EINVAL; } keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; keyconf->hw_key_idx = HW_KEY_DEFAULT; - il->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; + il->stations[IL_AP_ID].keyinfo.cipher = keyconf->cipher; - ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; - memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, - keyconf->keylen); + il->_4965.wep_keys[idx].key_size = len; + memcpy(&il->_4965.wep_keys[idx].key, &keyconf->key, len); - ret = il4965_static_wepkey_cmd(il, ctx, false); - D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", keyconf->keylen, - keyconf->keyidx, ret); + ret = il4965_static_wepkey_cmd(il, false); + D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", len, idx, ret); return ret; } static int -il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx, +il4965_set_wep_dynamic_key_info(struct il_priv *il, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -2939,7 +3213,7 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx, if (keyconf->keylen == WEP_KEY_LEN_128) key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; - if (sta_id == ctx->bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; spin_lock_irqsave(&il->sta_lock, flags); @@ -2976,7 +3250,6 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx, static int il4965_set_ccmp_dynamic_key_info(struct il_priv *il, - struct il_rxon_context *ctx, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -2989,7 +3262,7 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il, key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags &= ~STA_KEY_FLG_INVALID; - if (sta_id == ctx->bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -3025,7 +3298,6 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il, static int il4965_set_tkip_dynamic_key_info(struct il_priv *il, - struct il_rxon_context *ctx, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -3036,7 +3308,7 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il, key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags &= ~STA_KEY_FLG_INVALID; - if (sta_id == ctx->bcast_sta_id) + if (sta_id == il->hw_params.bcast_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -3070,9 +3342,8 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il, } void -il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 * phase1key) +il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) { u8 sta_id; unsigned long flags; @@ -3084,7 +3355,7 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, return; } - sta_id = il_sta_id_or_broadcast(il, ctx, sta); + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return; @@ -3102,11 +3373,10 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, il_send_add_sta(il, &il->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&il->sta_lock, flags); - } int -il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, +il4965_remove_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, u8 sta_id) { unsigned long flags; @@ -3116,7 +3386,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, lockdep_assert_held(&il->mutex); - ctx->key_mapping_keys--; + il->_4965.key_mapping_keys--; spin_lock_irqsave(&il->sta_lock, flags); key_flags = le16_to_cpu(il->stations[sta_id].sta.key.key_flags); @@ -3167,28 +3437,28 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, } int -il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, - struct ieee80211_key_conf *keyconf, u8 sta_id) +il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, + u8 sta_id) { int ret; lockdep_assert_held(&il->mutex); - ctx->key_mapping_keys++; + il->_4965.key_mapping_keys++; keyconf->hw_key_idx = HW_KEY_DYNAMIC; switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_CCMP: ret = - il4965_set_ccmp_dynamic_key_info(il, ctx, keyconf, sta_id); + il4965_set_ccmp_dynamic_key_info(il, keyconf, sta_id); break; case WLAN_CIPHER_SUITE_TKIP: ret = - il4965_set_tkip_dynamic_key_info(il, ctx, keyconf, sta_id); + il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id); break; case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - ret = il4965_set_wep_dynamic_key_info(il, ctx, keyconf, sta_id); + ret = il4965_set_wep_dynamic_key_info(il, keyconf, sta_id); break; default: IL_ERR("Unknown alg: %s cipher = %x\n", __func__, @@ -3210,14 +3480,14 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, * device at the next best time. */ int -il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) +il4965_alloc_bcast_station(struct il_priv *il) { struct il_link_quality_cmd *link_cmd; unsigned long flags; u8 sta_id; spin_lock_irqsave(&il->sta_lock, flags); - sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL); + sta_id = il_prep_station(il, il_bcast_addr, false, NULL); if (sta_id == IL_INVALID_STATION) { IL_ERR("Unable to prepare broadcast station\n"); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -3250,11 +3520,11 @@ il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) * code together. */ static int -il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) +il4965_update_bcast_station(struct il_priv *il) { unsigned long flags; struct il_link_quality_cmd *link_cmd; - u8 sta_id = ctx->bcast_sta_id; + u8 sta_id = il->hw_params.bcast_id; link_cmd = il4965_sta_alloc_lq(il, sta_id); if (!link_cmd) { @@ -3276,7 +3546,7 @@ il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx) int il4965_update_bcast_stations(struct il_priv *il) { - return il4965_update_bcast_station(il, &il->ctx); + return il4965_update_bcast_station(il); } /** @@ -3376,10 +3646,10 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt) void il4965_update_chain_flags(struct il_priv *il) { - if (il->cfg->ops->hcmd->set_rxon_chain) { - il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); - if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain) - il_commit_rxon(il, &il->ctx); + if (il->ops->set_rxon_chain) { + il->ops->set_rxon_chain(il); + if (il->active.rx_chain != il->staging.rx_chain) + il_commit_rxon(il); } } @@ -3491,8 +3761,8 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) lockdep_assert_held(&il->mutex); - if (!il->beacon_ctx) { - IL_ERR("trying to build beacon w/o beacon context!\n"); + if (!il->beacon_enabled) { + IL_ERR("Trying to build beacon without beaconing enabled\n"); return 0; } @@ -3511,7 +3781,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16) frame_size); - tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id; + tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | @@ -3522,7 +3792,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame) frame_size); /* Set up packet rate and flags */ - rate = il_get_lowest_plcp(il, il->beacon_ctx); + rate = il_get_lowest_plcp(il); il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant); rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS; if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE)) @@ -3645,15 +3915,13 @@ il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq) PCI_DMA_TODEVICE); /* free SKB */ - if (txq->txb) { - struct sk_buff *skb; - - skb = txq->txb[txq->q.read_ptr].skb; + if (txq->skbs) { + struct sk_buff *skb = txq->skbs[txq->q.read_ptr]; /* can be called from irqs-disabled context */ if (skb) { dev_kfree_skb_any(skb); - txq->txb[txq->q.read_ptr].skb = NULL; + txq->skbs[txq->q.read_ptr] = NULL; } } } @@ -3752,9 +4020,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb) * This callback is provided in order to send a stats request. * * This timer function is continually reset to execute within - * REG_RECALIB_PERIOD seconds since the last N_STATS - * was received. We need to ensure we receive the stats in order - * to update the temperature used for calibrating the TXPOWER. + * 60 seconds since the last N_STATS was received. We need to + * ensure we receive the stats in order to update the temperature + * used for calibrating the TXPOWER. */ static void il4965_bg_stats_periodic(unsigned long data) @@ -3804,7 +4072,7 @@ il4965_perform_ct_kill_task(struct il_priv *il) _il_rd(il, CSR_UCODE_DRV_GP1); spin_lock_irqsave(&il->reg_lock, flags); - if (!_il_grab_nic_access(il)) + if (likely(_il_grab_nic_access(il))) _il_release_nic_access(il); spin_unlock_irqrestore(&il->reg_lock, flags); } @@ -3842,17 +4110,17 @@ il4965_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb) il4965_perform_ct_kill_task(il); if (flags & HW_CARD_DISABLED) - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); else - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); if (!(flags & RXON_CARD_DISABLED)) il_scan_cancel(il); - if ((test_bit(S_RF_KILL_HW, &status) != - test_bit(S_RF_KILL_HW, &il->status))) + if ((test_bit(S_RFKILL, &status) != + test_bit(S_RFKILL, &il->status))) wiphy_rfkill_set_hw_state(il->hw->wiphy, - test_bit(S_RF_KILL_HW, &il->status)); + test_bit(S_RFKILL, &il->status)); else wake_up(&il->wait_command_queue); } @@ -3894,10 +4162,11 @@ il4965_setup_handlers(struct il_priv *il) /* Rx handlers */ il->handlers[N_RX_PHY] = il4965_hdl_rx_phy; il->handlers[N_RX_MPDU] = il4965_hdl_rx; + il->handlers[N_RX] = il4965_hdl_rx; /* block ack */ il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba; - /* Set up hardware specific Rx handlers */ - il->cfg->ops->lib->handler_setup(il); + /* Tx response */ + il->handlers[C_TX] = il4965_hdl_tx; } /** @@ -4127,9 +4396,8 @@ il4965_irq_tasklet(struct il_priv *il) /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { int hw_rf_kill = 0; - if (! - (_il_rd(il, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) + + if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; IL_WARN("RF_KILL bit toggled to %s.\n", @@ -4144,9 +4412,9 @@ il4965_irq_tasklet(struct il_priv *il) */ if (!test_bit(S_ALIVE, &il->status)) { if (hw_rf_kill) - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); else - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill); } @@ -4270,11 +4538,9 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr, ret = strict_strtoul(buf, 0, &val); if (ret) IL_ERR("%s is not in hex or decimal form.\n", buf); - else { + else il->debug_level = val; - if (il_alloc_traffic_mem(il)) - IL_ERR("Not enough memory to generate traffic log\n"); - } + return strnlen(buf, count); } @@ -4799,7 +5065,7 @@ il4965_dump_nic_error_log(struct il_priv *il) else base = le32_to_cpu(il->card_alive.error_event_table_ptr); - if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) { + if (!il->ops->is_valid_rtc_data_addr(base)) { IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n", base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT"); return; @@ -4979,7 +5245,6 @@ static void il4965_alive_start(struct il_priv *il) { int ret = 0; - struct il_rxon_context *ctx = &il->ctx; D_INFO("Runtime Alive received.\n"); @@ -5019,18 +5284,18 @@ il4965_alive_start(struct il_priv *il) il->active_rate = RATES_MASK; - if (il_is_associated_ctx(ctx)) { + if (il_is_associated(il)) { struct il_rxon_cmd *active_rxon = - (struct il_rxon_cmd *)&ctx->active; + (struct il_rxon_cmd *)&il->active; /* apply any changes in staging */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - il_connection_init_rx_config(il, &il->ctx); + il_connection_init_rx_config(il); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); } /* Configure bluetooth coexistence if enabled */ @@ -5041,7 +5306,7 @@ il4965_alive_start(struct il_priv *il) set_bit(S_READY, &il->status); /* Configure the adapter for unassociated operation */ - il_commit_rxon(il, ctx); + il_commit_rxon(il); /* At this point, the NIC is initialized and operational */ il4965_rf_kill_ct_config(il); @@ -5076,7 +5341,21 @@ __il4965_down(struct il_priv *il) * to prevent rearm timer */ del_timer_sync(&il->watchdog); - il_clear_ucode_stations(il, NULL); + il_clear_ucode_stations(il); + + /* FIXME: race conditions ? */ + spin_lock_irq(&il->sta_lock); + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(il->_4965.wep_keys, 0, sizeof(il->_4965.wep_keys)); + il->_4965.key_mapping_keys = 0; + spin_unlock_irq(&il->sta_lock); + il_dealloc_bcast_stations(il); il_clear_driver_stations(il); @@ -5104,12 +5383,8 @@ __il4965_down(struct il_priv *il) * clear all bits but the RF Kill bit and return */ if (!il_is_init(il)) { il->status = - test_bit(S_RF_KILL_HW, - &il-> - status) << S_RF_KILL_HW | - test_bit(S_GEO_CONFIGURED, - &il-> - status) << S_GEO_CONFIGURED | + test_bit(S_RFKILL, &il->status) << S_RFKILL | + test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED | test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; goto exit; } @@ -5117,28 +5392,32 @@ __il4965_down(struct il_priv *il) /* ...otherwise clear out all the status bits but the RF Kill * bit and continue taking the NIC down. */ il->status &= - test_bit(S_RF_KILL_HW, - &il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED, - &il-> - status) << - S_GEO_CONFIGURED | test_bit(S_FW_ERROR, - &il-> - status) << S_FW_ERROR | + test_bit(S_RFKILL, &il->status) << S_RFKILL | + test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED | + test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR | test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING; + /* + * We disabled and synchronized interrupt, and priv->mutex is taken, so + * here is the only thread which will program device registers, but + * still have lockdep assertions, so we are taking reg_lock. + */ + spin_lock_irq(&il->reg_lock); + /* FIXME: il_grab_nic_access if rfkill is off ? */ + il4965_txq_ctx_stop(il); il4965_rxq_stop(il); - /* Power-down device's busmaster DMA clocks */ - il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); + _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(5); - /* Make sure (redundant) we've released our request to stay awake */ - il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - + _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - il_apm_stop(il); + _il_apm_stop(il); + + spin_unlock_irq(&il->reg_lock); + il4965_txq_ctx_unmap(il); exit: memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); @@ -5159,40 +5438,36 @@ il4965_down(struct il_priv *il) il4965_cancel_deferred_work(il); } -#define HW_READY_TIMEOUT (50) -static int +static void il4965_set_hw_ready(struct il_priv *il) { - int ret = 0; + int ret; il_set_bit(il, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); /* See if we got it */ - ret = - _il_poll_bit(il, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, - CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); - if (ret != -ETIMEDOUT) + ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, + CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, + 100); + if (ret >= 0) il->hw_ready = true; - else - il->hw_ready = false; - D_INFO("hardware %s\n", (il->hw_ready == 1) ? "ready" : "not ready"); - return ret; + D_INFO("hardware %s ready\n", (il->hw_ready) ? "" : "not"); } -static int +static void il4965_prepare_card_hw(struct il_priv *il) { - int ret = 0; + int ret; - D_INFO("il4965_prepare_card_hw enter\n"); + il->hw_ready = false; - ret = il4965_set_hw_ready(il); + il4965_set_hw_ready(il); if (il->hw_ready) - return ret; + return; /* If HW is not ready, prepare the conditions to check again */ il_set_bit(il, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); @@ -5205,8 +5480,6 @@ il4965_prepare_card_hw(struct il_priv *il) /* HW should be ready by now, check again. */ if (ret != -ETIMEDOUT) il4965_set_hw_ready(il); - - return ret; } #define MAX_HW_RESTARTS 5 @@ -5227,29 +5500,26 @@ __il4965_up(struct il_priv *il) return -EIO; } - ret = il4965_alloc_bcast_station(il, &il->ctx); + ret = il4965_alloc_bcast_station(il); if (ret) { il_dealloc_bcast_stations(il); return ret; } il4965_prepare_card_hw(il); - if (!il->hw_ready) { - IL_WARN("Exit HW not ready\n"); + IL_ERR("HW not ready\n"); return -EIO; } /* If platform's RF_KILL switch is NOT set to KILL */ if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(S_RF_KILL_HW, &il->status); - else - set_bit(S_RF_KILL_HW, &il->status); - - if (il_is_rfkill(il)) { + clear_bit(S_RFKILL, &il->status); + else { + set_bit(S_RFKILL, &il->status); wiphy_rfkill_set_hw_state(il->hw->wiphy, true); - il_enable_interrupts(il); + il_enable_rfkill_int(il); IL_WARN("Radio disabled by HW RF Kill switch\n"); return 0; } @@ -5288,7 +5558,7 @@ __il4965_up(struct il_priv *il) /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - ret = il->cfg->ops->lib->load_ucode(il); + ret = il->ops->load_ucode(il); if (ret) { IL_ERR("Unable to set up bootstrap uCode: %d\n", ret); @@ -5329,7 +5599,7 @@ il4965_bg_init_alive_start(struct work_struct *data) if (test_bit(S_EXIT_PENDING, &il->status)) goto out; - il->cfg->ops->lib->init_alive_start(il); + il->ops->init_alive_start(il); out: mutex_unlock(&il->mutex); } @@ -5381,7 +5651,8 @@ il4965_bg_restart(struct work_struct *data) if (test_and_clear_bit(S_FW_ERROR, &il->status)) { mutex_lock(&il->mutex); - il->ctx.vif = NULL; + /* FIXME: do we dereference vif without mutex locked ? */ + il->vif = NULL; il->is_open = 0; __il4965_down(il); @@ -5450,8 +5721,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) hw->sta_data_size = sizeof(struct il_station_priv); hw->vif_data_size = sizeof(struct il_vif_priv); - hw->wiphy->interface_modes |= il->ctx.interface_modes; - hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes; + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -5578,12 +5849,10 @@ il4965_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u32 iv32, u16 * phase1key) { struct il_priv *il = hw->priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; D_MAC80211("enter\n"); - il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta, iv32, - phase1key); + il4965_update_tkip_key(il, keyconf, sta, iv32, phase1key); D_MAC80211("leave\n"); } @@ -5594,8 +5863,6 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct il_priv *il = hw->priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; - struct il_rxon_context *ctx = vif_priv->ctx; int ret; u8 sta_id; bool is_default_wep_key = false; @@ -5607,7 +5874,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta); + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return -EINVAL; @@ -5623,7 +5890,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) { if (cmd == SET_KEY) - is_default_wep_key = !ctx->key_mapping_keys; + is_default_wep_key = !il->_4965.key_mapping_keys; else is_default_wep_key = (key->hw_key_idx == HW_KEY_DEFAULT); @@ -5632,20 +5899,17 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: if (is_default_wep_key) - ret = - il4965_set_default_wep_key(il, vif_priv->ctx, key); + ret = il4965_set_default_wep_key(il, key); else - ret = - il4965_set_dynamic_key(il, vif_priv->ctx, key, - sta_id); + ret = il4965_set_dynamic_key(il, key, sta_id); D_MAC80211("enable hwcrypto key\n"); break; case DISABLE_KEY: if (is_default_wep_key) - ret = il4965_remove_default_wep_key(il, ctx, key); + ret = il4965_remove_default_wep_key(il, key); else - ret = il4965_remove_dynamic_key(il, ctx, key, sta_id); + ret = il4965_remove_dynamic_key(il, key, sta_id); D_MAC80211("disable hwcrypto key\n"); break; @@ -5711,7 +5975,6 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct il_priv *il = hw->priv; struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; bool is_ap = vif->type == NL80211_IFTYPE_STATION; int ret; u8 sta_id; @@ -5724,8 +5987,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, atomic_set(&sta_priv->pending_frames, 0); ret = - il_add_station_common(il, vif_priv->ctx, sta->addr, is_ap, sta, - &sta_id); + il_add_station_common(il, sta->addr, is_ap, sta, &sta_id); if (ret) { IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ @@ -5752,8 +6014,6 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = ch_switch->channel; struct il_ht_config *ht_conf = &il->current_ht_config; - - struct il_rxon_context *ctx = &il->ctx; u16 ch; D_MAC80211("enter\n"); @@ -5768,14 +6028,14 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, test_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) goto out; - if (!il_is_associated_ctx(ctx)) + if (!il_is_associated(il)) goto out; - if (!il->cfg->ops->lib->set_channel_switch) + if (!il->ops->set_channel_switch) goto out; ch = channel->hw_value; - if (le16_to_cpu(ctx->active.channel) == ch) + if (le16_to_cpu(il->active.channel) == ch) goto out; ch_info = il_get_channel_info(il, channel->band, ch); @@ -5789,30 +6049,30 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, il->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ - ctx->ht.enabled = conf_is_ht(conf); - if (ctx->ht.enabled) { + il->ht.enabled = conf_is_ht(conf); + if (il->ht.enabled) { if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; } } else - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; + if ((le16_to_cpu(il->staging.channel) != ch)) + il->staging.flags = 0; - il_set_rxon_channel(il, channel, ctx); + il_set_rxon_channel(il, channel); il_set_rxon_ht(il, ht_conf); - il_set_flags_for_band(il, ctx, channel->band, ctx->vif); + il_set_flags_for_band(il, channel->band, il->vif); spin_unlock_irq(&il->lock); @@ -5823,10 +6083,10 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, */ set_bit(S_CHANNEL_SWITCH_PENDING, &il->status); il->switch_channel = cpu_to_le16(ch); - if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) { + if (il->ops->set_channel_switch(il, ch_switch)) { clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status); il->switch_channel = 0; - ieee80211_chswitch_done(ctx->vif, false); + ieee80211_chswitch_done(il->vif, false); } out: @@ -5860,8 +6120,8 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, mutex_lock(&il->mutex); - il->ctx.staging.filter_flags &= ~filter_nand; - il->ctx.staging.filter_flags |= filter_or; + il->staging.filter_flags &= ~filter_nand; + il->staging.filter_flags |= filter_or; /* * Not committing directly because hardware can perform a scan, @@ -5906,7 +6166,7 @@ il4965_bg_txpower_work(struct work_struct *work) /* Regardless of if we are associated, we must reconfigure the * TX power since frames can be sent on non-radar channels while * not associated */ - il->cfg->ops->lib->send_tx_power(il); + il->ops->send_tx_power(il); /* Update last_temperature to keep is_calib_needed from running * when it isn't needed... */ @@ -6012,6 +6272,28 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); } +const struct ieee80211_ops il4965_mac_ops = { + .tx = il4965_mac_tx, + .start = il4965_mac_start, + .stop = il4965_mac_stop, + .add_interface = il_mac_add_interface, + .remove_interface = il_mac_remove_interface, + .change_interface = il_mac_change_interface, + .config = il_mac_config, + .configure_filter = il4965_configure_filter, + .set_key = il4965_mac_set_key, + .update_tkip_key = il4965_mac_update_tkip_key, + .conf_tx = il_mac_conf_tx, + .reset_tsf = il_mac_reset_tsf, + .bss_info_changed = il_mac_bss_info_changed, + .ampdu_action = il4965_mac_ampdu_action, + .hw_scan = il_mac_hw_scan, + .sta_add = il4965_mac_sta_add, + .sta_remove = il_mac_sta_remove, + .channel_switch = il4965_mac_channel_switch, + .tx_last_beacon = il_mac_tx_last_beacon, +}; + static int il4965_init_drv(struct il_priv *il) { @@ -6036,8 +6318,8 @@ il4965_init_drv(struct il_priv *il) il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD; /* Choose which receivers/antennas to use */ - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); il_init_scan_params(il); @@ -6065,7 +6347,6 @@ err: static void il4965_uninit_drv(struct il_priv *il) { - il4965_calib_free_results(il); il_free_geos(il); il_free_channel_map(il); kfree(il->scan_cmd); @@ -6080,9 +6361,37 @@ il4965_hw_detect(struct il_priv *il) D_INFO("HW Revision ID = 0x%X\n", il->rev_id); } -static int +static struct il_sensitivity_ranges il4965_sensitivity = { + .min_nrg_cck = 97, + .max_nrg_cck = 0, /* not used, set to 0 */ + + .auto_corr_min_ofdm = 85, + .auto_corr_min_ofdm_mrc = 170, + .auto_corr_min_ofdm_x1 = 105, + .auto_corr_min_ofdm_mrc_x1 = 220, + + .auto_corr_max_ofdm = 120, + .auto_corr_max_ofdm_mrc = 210, + .auto_corr_max_ofdm_x1 = 140, + .auto_corr_max_ofdm_mrc_x1 = 270, + + .auto_corr_min_cck = 125, + .auto_corr_max_cck = 200, + .auto_corr_min_cck_mrc = 200, + .auto_corr_max_cck_mrc = 400, + + .nrg_th_cck = 100, + .nrg_th_ofdm = 100, + + .barker_corr_th_min = 190, + .barker_corr_th_min_mrc = 390, + .nrg_th_cca = 62, +}; + +static void il4965_set_hw_params(struct il_priv *il) { + il->hw_params.bcast_id = IL4965_BROADCAST_ID; il->hw_params.max_rxq_size = RX_QUEUE_SIZE; il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; if (il->cfg->mod_params->amsdu_size_8K) @@ -6095,20 +6404,37 @@ il4965_set_hw_params(struct il_priv *il) if (il->cfg->mod_params->disable_11n) il->cfg->sku &= ~IL_SKU_N; - /* Device-specific setup */ - return il->cfg->ops->lib->set_hw_params(il); -} + if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES && + il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES) + il->cfg->num_of_queues = + il->cfg->mod_params->num_of_queues; -static const u8 il4965_bss_ac_to_fifo[] = { - IL_TX_FIFO_VO, - IL_TX_FIFO_VI, - IL_TX_FIFO_BE, - IL_TX_FIFO_BK, -}; + il->hw_params.max_txq_num = il->cfg->num_of_queues; + il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; + il->hw_params.scd_bc_tbls_size = + il->cfg->num_of_queues * + sizeof(struct il4965_scd_bc_tbl); -static const u8 il4965_bss_ac_to_queue[] = { - 0, 1, 2, 3, -}; + il->hw_params.tfd_size = sizeof(struct il_tfd); + il->hw_params.max_stations = IL4965_STATION_COUNT; + il->hw_params.max_data_size = IL49_RTC_DATA_SIZE; + il->hw_params.max_inst_size = IL49_RTC_INST_SIZE; + il->hw_params.max_bsm_size = BSM_SRAM_SIZE; + il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); + + il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR; + + il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant); + il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant); + il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant; + il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant; + + il->hw_params.ct_kill_threshold = + CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); + + il->hw_params.sens = &il4965_sensitivity; + il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS; +} static int il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -6124,43 +6450,24 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 1. Allocating HW data ************************/ - hw = il_alloc_all(cfg); + hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il4965_mac_ops); if (!hw) { err = -ENOMEM; goto out; } il = hw->priv; - /* At this point both hw and il are allocated. */ - - il->ctx.ctxid = 0; - - il->ctx.always_active = true; - il->ctx.is_active = true; - il->ctx.rxon_cmd = C_RXON; - il->ctx.rxon_timing_cmd = C_RXON_TIMING; - il->ctx.rxon_assoc_cmd = C_RXON_ASSOC; - il->ctx.qos_cmd = C_QOS_PARAM; - il->ctx.ap_sta_id = IL_AP_ID; - il->ctx.wep_key_cmd = C_WEPKEY; - il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo; - il->ctx.ac_to_queue = il4965_bss_ac_to_queue; - il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); - il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION); - il->ctx.ap_devtype = RXON_DEV_TYPE_AP; - il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS; - il->ctx.station_devtype = RXON_DEV_TYPE_ESS; - il->ctx.unused_devtype = RXON_DEV_TYPE_ESS; - + il->hw = hw; SET_IEEE80211_DEV(hw, &pdev->dev); D_INFO("*** LOAD DRIVER ***\n"); il->cfg = cfg; + il->ops = &il4965_ops; +#ifdef CONFIG_IWLEGACY_DEBUGFS + il->debugfs_ops = &il4965_debugfs_ops; +#endif il->pci_dev = pdev; il->inta_mask = CSR_INI_SET_MASK; - if (il_alloc_traffic_mem(il)) - IL_ERR("Not enough memory to generate traffic log\n"); - /************************** * 2. Initializing PCI bus **************************/ @@ -6199,7 +6506,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /*********************** * 3. Read REV register ***********************/ - il->hw_base = pci_iomap(pdev, 0, 0); + il->hw_base = pci_ioremap_bar(pdev, 0); if (!il->hw_base) { err = -ENODEV; goto out_pci_release_regions; @@ -6260,10 +6567,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /************************ * 5. Setup HW constants ************************/ - if (il4965_set_hw_params(il)) { - IL_ERR("failed to set hw parameters\n"); - goto out_free_eeprom; - } + il4965_set_hw_params(il); /******************* * 6. Setup il @@ -6307,12 +6611,12 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* If platform's RF_KILL switch is NOT set to KILL */ if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); else - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); wiphy_rfkill_set_hw_state(il->hw->wiphy, - test_bit(S_RF_KILL_HW, &il->status)); + test_bit(S_RFKILL, &il->status)); il_power_initialize(il); @@ -6334,14 +6638,13 @@ out_disable_msi: out_free_eeprom: il_eeprom_free(il); out_iounmap: - pci_iounmap(pdev, il->hw_base); + iounmap(il->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: - il_free_traffic_mem(il); ieee80211_free_hw(il->hw); out: return err; @@ -6412,11 +6715,10 @@ il4965_pci_remove(struct pci_dev *pdev) * until now... */ destroy_workqueue(il->workqueue); il->workqueue = NULL; - il_free_traffic_mem(il); free_irq(il->pci_dev->irq, il); pci_disable_msi(il->pci_dev); - pci_iounmap(pdev, il->hw_base); + iounmap(il->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 467d0cb14ec..d7e2856e41d 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c @@ -641,13 +641,10 @@ il4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, * there are no non-GF stations present in the BSS. */ static bool -il4965_rs_use_green(struct ieee80211_sta *sta) +il4965_rs_use_green(struct il_priv *il, struct ieee80211_sta *sta) { - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; - return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && - !(ctx->ht.non_gf_sta_present); + !il->ht.non_gf_sta_present; } /** @@ -823,8 +820,6 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband, u32 tx_rate; struct il_scale_tbl_info tbl_type; struct il_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; D_RATE("get frame ack response, update rate scale win\n"); @@ -892,7 +887,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband, lq_sta->missed_rate_counter++; if (lq_sta->missed_rate_counter > IL_MISSED_RATE_MAX) { lq_sta->missed_rate_counter = 0; - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); } /* Regardless, ignore this status info for outdated rate */ return; @@ -1184,8 +1179,6 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta, u16 rate_mask; s32 rate; s8 is_green = lq_sta->is_green; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1206,7 +1199,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta, tbl->max_search = IL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1240,8 +1233,6 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta, u16 rate_mask; u8 is_green = lq_sta->is_green; s32 rate; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1254,7 +1245,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta, tbl->max_search = IL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1733,8 +1724,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search) * setup rate table in uCode */ static void -il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx, - struct il_lq_sta *lq_sta, +il4965_rs_update_rate_tbl(struct il_priv *il, struct il_lq_sta *lq_sta, struct il_scale_tbl_info *tbl, int idx, u8 is_green) { u32 rate; @@ -1742,7 +1732,7 @@ il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx, /* Update uCode's rate table. */ rate = il4965_rate_n_flags_from_tbl(il, tbl, idx, is_green); il4965_rs_fill_link_cmd(il, lq_sta, rate); - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); } /* @@ -1778,8 +1768,6 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, s32 sr; u8 tid = MAX_TID_COUNT; struct il_tid_data *tid_data; - struct il_station_priv *sta_priv = (void *)sta->drv_priv; - struct il_rxon_context *ctx = sta_priv->common.ctx; D_RATE("rate scale calculate new rate for skb\n"); @@ -1815,7 +1803,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, if (is_legacy(tbl->lq_type)) lq_sta->is_green = 0; else - lq_sta->is_green = il4965_rs_use_green(sta); + lq_sta->is_green = il4965_rs_use_green(il, sta); is_green = lq_sta->is_green; /* current tx rate */ @@ -1854,7 +1842,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); /* get "active" rate info */ idx = il4965_hwrate_to_plcp_idx(tbl->current_rate); - il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx, + il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green); } return; @@ -2057,8 +2045,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb, lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) - il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx, - is_green); + il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green); /* Should we stay with this modulation mode, * or search for a new one? */ @@ -2098,7 +2085,7 @@ lq_update: D_RATE("Switch current mcs: %X idx: %d\n", tbl->current_rate, idx); il4965_rs_fill_link_cmd(il, lq_sta, tbl->current_rate); - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false); } else done_search = 1; } @@ -2166,17 +2153,15 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, int rate_idx; int i; u32 rate; - u8 use_green = il4965_rs_use_green(sta); + u8 use_green = il4965_rs_use_green(il, sta); u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; - struct il_rxon_context *ctx; if (!sta || !lq_sta) return; sta_priv = (void *)sta->drv_priv; - ctx = sta_priv->common.ctx; i = lq_sta->last_txrate_idx; @@ -2208,7 +2193,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, il4965_rs_set_expected_tpt_table(lq_sta, tbl); il4965_rs_fill_link_cmd(NULL, lq_sta, rate); il->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; - il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_SYNC, true); + il_send_lq_cmd(il, &lq_sta->lq, CMD_SYNC, true); } static void @@ -2341,7 +2326,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) lq_sta->is_dup = 0; lq_sta->max_rate_idx = -1; lq_sta->missed_rate_counter = IL_MISSED_RATE_MAX; - lq_sta->is_green = il4965_rs_use_green(sta); + lq_sta->is_green = il4965_rs_use_green(il, sta); lq_sta->active_legacy_rate = il->active_rate & ~(0x1000); lq_sta->band = il->band; /* @@ -2579,9 +2564,6 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file, char buf[64]; size_t buf_size; u32 parsed_rate; - struct il_station_priv *sta_priv = - container_of(lq_sta, struct il_station_priv, lq_sta); - struct il_rxon_context *ctx = sta_priv->common.ctx; il = lq_sta->drv; memset(buf, 0, sizeof(buf)); @@ -2603,7 +2585,7 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file, if (lq_sta->dbg_fixed_rate) { il4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); - il_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, false); + il_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); } return count; diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index cacbc03880b..5db11714e04 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -264,10 +264,6 @@ il4965_led_enable(struct il_priv *il) _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON); } -const struct il_led_ops il4965_led_ops = { - .cmd = il4965_send_led_cmd, -}; - static int il4965_send_tx_power(struct il_priv *il); static int il4965_hw_get_temperature(struct il_priv *il); @@ -508,7 +504,7 @@ iw4965_is_ht40_channel(__le32 rxon_flags) chan_mod == CHANNEL_MODE_MIXED); } -static void +void il4965_nic_config(struct il_priv *il) { unsigned long flags; @@ -569,82 +565,6 @@ il4965_chain_noise_reset(struct il_priv *il) } } -static struct il_sensitivity_ranges il4965_sensitivity = { - .min_nrg_cck = 97, - .max_nrg_cck = 0, /* not used, set to 0 */ - - .auto_corr_min_ofdm = 85, - .auto_corr_min_ofdm_mrc = 170, - .auto_corr_min_ofdm_x1 = 105, - .auto_corr_min_ofdm_mrc_x1 = 220, - - .auto_corr_max_ofdm = 120, - .auto_corr_max_ofdm_mrc = 210, - .auto_corr_max_ofdm_x1 = 140, - .auto_corr_max_ofdm_mrc_x1 = 270, - - .auto_corr_min_cck = 125, - .auto_corr_max_cck = 200, - .auto_corr_min_cck_mrc = 200, - .auto_corr_max_cck_mrc = 400, - - .nrg_th_cck = 100, - .nrg_th_ofdm = 100, - - .barker_corr_th_min = 190, - .barker_corr_th_min_mrc = 390, - .nrg_th_cca = 62, -}; - -static void -il4965_set_ct_threshold(struct il_priv *il) -{ - /* want Kelvin */ - il->hw_params.ct_kill_threshold = - CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY); -} - -/** - * il4965_hw_set_hw_params - * - * Called when initializing driver - */ -static int -il4965_hw_set_hw_params(struct il_priv *il) -{ - if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES && - il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES) - il->cfg->base_params->num_of_queues = - il->cfg->mod_params->num_of_queues; - - il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues; - il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; - il->hw_params.scd_bc_tbls_size = - il->cfg->base_params->num_of_queues * - sizeof(struct il4965_scd_bc_tbl); - il->hw_params.tfd_size = sizeof(struct il_tfd); - il->hw_params.max_stations = IL4965_STATION_COUNT; - il->ctx.bcast_sta_id = IL4965_BROADCAST_ID; - il->hw_params.max_data_size = IL49_RTC_DATA_SIZE; - il->hw_params.max_inst_size = IL49_RTC_INST_SIZE; - il->hw_params.max_bsm_size = BSM_SRAM_SIZE; - il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ); - - il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR; - - il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant); - il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant); - il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant; - il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant; - - il4965_set_ct_threshold(il); - - il->hw_params.sens = &il4965_sensitivity; - il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS; - - return 0; -} - static s32 il4965_math_div_round(s32 num, s32 denom, s32 * res) { @@ -1342,7 +1262,6 @@ il4965_send_tx_power(struct il_priv *il) u8 band = 0; bool is_ht40 = false; u8 ctrl_chan_high = 0; - struct il_rxon_context *ctx = &il->ctx; if (WARN_ONCE (test_bit(S_SCAN_HW, &il->status), @@ -1351,16 +1270,16 @@ il4965_send_tx_power(struct il_priv *il) band = il->band == IEEE80211_BAND_2GHZ; - is_ht40 = iw4965_is_ht40_channel(ctx->active.flags); + is_ht40 = iw4965_is_ht40_channel(il->active.flags); - if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; - cmd.channel = ctx->active.channel; + cmd.channel = il->active.channel; ret = - il4965_fill_txpower_tbl(il, band, le16_to_cpu(ctx->active.channel), + il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel), is_ht40, ctrl_chan_high, &cmd.tx_power); if (ret) goto out; @@ -1372,12 +1291,12 @@ out: } static int -il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) +il4965_send_rxon_assoc(struct il_priv *il) { int ret = 0; struct il4965_rxon_assoc_cmd rxon_assoc; - const struct il_rxon_cmd *rxon1 = &ctx->staging; - const struct il_rxon_cmd *rxon2 = &ctx->active; + const struct il_rxon_cmd *rxon1 = &il->staging; + const struct il_rxon_cmd *rxon2 = &il->active; if (rxon1->flags == rxon2->flags && rxon1->filter_flags == rxon2->filter_flags && @@ -1392,16 +1311,16 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) return 0; } - rxon_assoc.flags = ctx->staging.flags; - rxon_assoc.filter_flags = ctx->staging.filter_flags; - rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; + rxon_assoc.flags = il->staging.flags; + rxon_assoc.filter_flags = il->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates; rxon_assoc.reserved = 0; rxon_assoc.ofdm_ht_single_stream_basic_rates = - ctx->staging.ofdm_ht_single_stream_basic_rates; + il->staging.ofdm_ht_single_stream_basic_rates; rxon_assoc.ofdm_ht_dual_stream_basic_rates = - ctx->staging.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; + il->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = il->staging.rx_chain; ret = il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc), @@ -1411,23 +1330,20 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) } static int -il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) +il4965_commit_rxon(struct il_priv *il) { /* cast away the const for active_rxon in this function */ - struct il_rxon_cmd *active_rxon = (void *)&ctx->active; + struct il_rxon_cmd *active_rxon = (void *)&il->active; int ret; - bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK); if (!il_is_alive(il)) return -EBUSY; - if (!ctx->is_active) - return 0; - /* always get timestamp with Rx frame */ - ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; + il->staging.flags |= RXON_FLG_TSF2HOST_MSK; - ret = il_check_rxon_cmd(il, ctx); + ret = il_check_rxon_cmd(il); if (ret) { IL_ERR("Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -1438,7 +1354,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) * abort any previous channel switch if still in process */ if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) && - il->switch_channel != ctx->staging.channel) { + il->switch_channel != il->staging.channel) { D_11H("abort channel switch on %d\n", le16_to_cpu(il->switch_channel)); il_chswitch_done(il, false); @@ -1447,15 +1363,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) /* If we don't need to send a full RXON, we can use * il_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!il_full_rxon_required(il, ctx)) { - ret = il_send_rxon_assoc(il, ctx); + if (!il_full_rxon_required(il)) { + ret = il_send_rxon_assoc(il); if (ret) { IL_ERR("Error setting RXON_ASSOC (%d)\n", ret); return ret; } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - il_print_rx_config_cmd(il, ctx); + memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); + il_print_rx_config_cmd(il); /* * We do not commit tx power settings while channel changing, * do it now if tx power changed. @@ -1468,12 +1384,12 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) * an RXON_ASSOC and the new config wants the associated mask enabled, * we must clear the associated from the active configuration * before we apply the new config */ - if (il_is_associated_ctx(ctx) && new_assoc) { + if (il_is_associated(il) && new_assoc) { D_INFO("Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; ret = - il_send_cmd_pdu(il, ctx->rxon_cmd, + il_send_cmd_pdu(il, C_RXON, sizeof(struct il_rxon_cmd), active_rxon); /* If the mask clearing failed then we set @@ -1483,9 +1399,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret); return ret; } - il_clear_ucode_stations(il, ctx); - il_restore_stations(il, ctx); - ret = il4965_restore_default_wep_keys(il, ctx); + il_clear_ucode_stations(il); + il_restore_stations(il); + ret = il4965_restore_default_wep_keys(il); if (ret) { IL_ERR("Failed to restore WEP keys (%d)\n", ret); return ret; @@ -1494,9 +1410,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n" "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"), - le16_to_cpu(ctx->staging.channel), ctx->staging.bssid_addr); + le16_to_cpu(il->staging.channel), il->staging.bssid_addr); - il_set_rxon_hwcrypto(il, ctx, !il->cfg->mod_params->sw_crypto); + il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto); /* Apply the new configuration * RXON unassoc clears the station table in uCode so restoration of @@ -1504,17 +1420,17 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) */ if (!new_assoc) { ret = - il_send_cmd_pdu(il, ctx->rxon_cmd, - sizeof(struct il_rxon_cmd), &ctx->staging); + il_send_cmd_pdu(il, C_RXON, + sizeof(struct il_rxon_cmd), &il->staging); if (ret) { IL_ERR("Error setting new RXON (%d)\n", ret); return ret; } D_INFO("Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); - il_clear_ucode_stations(il, ctx); - il_restore_stations(il, ctx); - ret = il4965_restore_default_wep_keys(il, ctx); + memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); + il_clear_ucode_stations(il); + il_restore_stations(il); + ret = il4965_restore_default_wep_keys(il); if (ret) { IL_ERR("Failed to restore WEP keys (%d)\n", ret); return ret; @@ -1526,15 +1442,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) * RXON assoc doesn't clear the station table in uCode, */ ret = - il_send_cmd_pdu(il, ctx->rxon_cmd, - sizeof(struct il_rxon_cmd), &ctx->staging); + il_send_cmd_pdu(il, C_RXON, + sizeof(struct il_rxon_cmd), &il->staging); if (ret) { IL_ERR("Error setting new RXON (%d)\n", ret); return ret; } - memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + memcpy(active_rxon, &il->staging, sizeof(*active_rxon)); } - il_print_rx_config_cmd(il, ctx); + il_print_rx_config_cmd(il); il4965_init_sensitivity(il); @@ -1553,7 +1469,6 @@ static int il4965_hw_channel_switch(struct il_priv *il, struct ieee80211_channel_switch *ch_switch) { - struct il_rxon_context *ctx = &il->ctx; int rc; u8 band = 0; bool is_ht40 = false; @@ -1564,21 +1479,24 @@ il4965_hw_channel_switch(struct il_priv *il, u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); - struct ieee80211_vif *vif = ctx->vif; - band = il->band == IEEE80211_BAND_2GHZ; + u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval); + struct ieee80211_vif *vif = il->vif; + band = (il->band == IEEE80211_BAND_2GHZ); + + if (WARN_ON_ONCE(vif == NULL)) + return -EIO; - is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags); + is_ht40 = iw4965_is_ht40_channel(il->staging.flags); - if (is_ht40 && (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; cmd.expect_beacon = 0; ch = ch_switch->channel->hw_value; cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = ctx->staging.flags; - cmd.rxon_filter_flags = ctx->staging.filter_flags; + cmd.rxon_flags = il->staging.flags; + cmd.rxon_filter_flags = il->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -1611,7 +1529,7 @@ il4965_hw_channel_switch(struct il_priv *il, cmd.expect_beacon = il_is_channel_radar(ch_info); else { IL_ERR("invalid channel switch from %u to %u\n", - ctx->active.channel, ch); + il->active.channel, ch); return -EFAULT; } @@ -1756,7 +1674,7 @@ il4965_is_temp_calib_needed(struct il_priv *il) return 1; } -static void +void il4965_temperature_calib(struct il_priv *il) { s32 temp; @@ -1815,339 +1733,21 @@ il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data) return (u16) sizeof(struct il4965_addsta_cmd); } -static inline u32 -il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp) -{ - return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; -} - -static inline u32 -il4965_tx_status_to_mac80211(u32 status) -{ - status &= TX_STATUS_MSK; - - switch (status) { - case TX_STATUS_SUCCESS: - case TX_STATUS_DIRECT_DONE: - return IEEE80211_TX_STAT_ACK; - case TX_STATUS_FAIL_DEST_PS: - return IEEE80211_TX_STAT_TX_FILTERED; - default: - return 0; - } -} - -static inline bool -il4965_is_tx_success(u32 status) -{ - status &= TX_STATUS_MSK; - return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE); -} - -/** - * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue - */ -static int -il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg, - struct il4965_tx_resp *tx_resp, int txq_id, - u16 start_idx) -{ - u16 status; - struct agg_tx_status *frame_status = tx_resp->u.agg_status; - struct ieee80211_tx_info *info = NULL; - struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); - int i, sh, idx; - u16 seq; - if (agg->wait_for_ba) - D_TX_REPLY("got tx response w/o block-ack\n"); - - agg->frame_count = tx_resp->frame_count; - agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; - agg->bitmap = 0; - - /* num frames attempted by Tx command */ - if (agg->frame_count == 1) { - /* Only one frame was attempted; no block-ack will arrive */ - status = le16_to_cpu(frame_status[0].status); - idx = start_idx; - - D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", - agg->frame_count, agg->start_idx, idx); - - info = IEEE80211_SKB_CB(il->txq[txq_id].txb[idx].skb); - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags &= ~IEEE80211_TX_CTL_AMPDU; - info->flags |= il4965_tx_status_to_mac80211(status); - il4965_hwrate_to_tx_control(il, rate_n_flags, info); - - D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff, - tx_resp->failure_frame); - D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); - - agg->wait_for_ba = 0; - } else { - /* Two or more frames were attempted; expect block-ack */ - u64 bitmap = 0; - int start = agg->start_idx; - - /* Construct bit-map of pending frames within Tx win */ - for (i = 0; i < agg->frame_count; i++) { - u16 sc; - status = le16_to_cpu(frame_status[i].status); - seq = le16_to_cpu(frame_status[i].sequence); - idx = SEQ_TO_IDX(seq); - txq_id = SEQ_TO_QUEUE(seq); - - if (status & - (AGG_TX_STATE_FEW_BYTES_MSK | - AGG_TX_STATE_ABORT_MSK)) - continue; - - D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n", - agg->frame_count, txq_id, idx); - - hdr = il_tx_queue_get_hdr(il, txq_id, idx); - if (!hdr) { - IL_ERR("BUG_ON idx doesn't point to valid skb" - " idx=%d, txq_id=%d\n", idx, txq_id); - return -1; - } - - sc = le16_to_cpu(hdr->seq_ctrl); - if (idx != (SEQ_TO_SN(sc) & 0xff)) { - IL_ERR("BUG_ON idx doesn't match seq control" - " idx=%d, seq_idx=%d, seq=%d\n", idx, - SEQ_TO_SN(sc), hdr->seq_ctrl); - return -1; - } - - D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx, - SEQ_TO_SN(sc)); - - sh = idx - start; - if (sh > 64) { - sh = (start - idx) + 0xff; - bitmap = bitmap << sh; - sh = 0; - start = idx; - } else if (sh < -64) - sh = 0xff - (start - idx); - else if (sh < 0) { - sh = start - idx; - start = idx; - bitmap = bitmap << sh; - sh = 0; - } - bitmap |= 1ULL << sh; - D_TX_REPLY("start=%d bitmap=0x%llx\n", start, - (unsigned long long)bitmap); - } - - agg->bitmap = bitmap; - agg->start_idx = start; - D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", - agg->frame_count, agg->start_idx, - (unsigned long long)agg->bitmap); - - if (bitmap) - agg->wait_for_ba = 1; - } - return 0; -} - -static u8 -il4965_find_station(struct il_priv *il, const u8 * addr) -{ - int i; - int start = 0; - int ret = IL_INVALID_STATION; - unsigned long flags; - - if ((il->iw_mode == NL80211_IFTYPE_ADHOC)) - start = IL_STA_ID; - - if (is_broadcast_ether_addr(addr)) - return il->ctx.bcast_sta_id; - - spin_lock_irqsave(&il->sta_lock, flags); - for (i = start; i < il->hw_params.max_stations; i++) - if (il->stations[i].used && - (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) { - ret = i; - goto out; - } - - D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations); - -out: - /* - * It may be possible that more commands interacting with stations - * arrive before we completed processing the adding of - * station - */ - if (ret != IL_INVALID_STATION && - (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) || - ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) && - (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) { - IL_ERR("Requested station info for sta %d before ready.\n", - ret); - ret = IL_INVALID_STATION; - } - spin_unlock_irqrestore(&il->sta_lock, flags); - return ret; -} - -static int -il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr) -{ - if (il->iw_mode == NL80211_IFTYPE_STATION) { - return IL_AP_ID; - } else { - u8 *da = ieee80211_get_DA(hdr); - return il4965_find_station(il, da); - } -} - -/** - * il4965_hdl_tx - Handle standard (non-aggregation) Tx response - */ -static void -il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) -{ - struct il_rx_pkt *pkt = rxb_addr(rxb); - u16 sequence = le16_to_cpu(pkt->hdr.sequence); - int txq_id = SEQ_TO_QUEUE(sequence); - int idx = SEQ_TO_IDX(sequence); - struct il_tx_queue *txq = &il->txq[txq_id]; - struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *info; - struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->u.status); - int uninitialized_var(tid); - int sta_id; - int freed; - u8 *qc = NULL; - unsigned long flags; - - if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) { - IL_ERR("Read idx for DMA queue txq_id (%d) idx %d " - "is out of range [0-%d] %d %d\n", txq_id, idx, - txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr); - return; - } - - txq->time_stamp = jiffies; - info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); - memset(&info->status, 0, sizeof(info->status)); - - hdr = il_tx_queue_get_hdr(il, txq_id, idx); - if (ieee80211_is_data_qos(hdr->frame_control)) { - qc = ieee80211_get_qos_ctl(hdr); - tid = qc[0] & 0xf; - } - - sta_id = il4965_get_ra_sta_id(il, hdr); - if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) { - IL_ERR("Station not known\n"); - return; - } - - spin_lock_irqsave(&il->sta_lock, flags); - if (txq->sched_retry) { - const u32 scd_ssn = il4965_get_scd_ssn(tx_resp); - struct il_ht_agg *agg = NULL; - WARN_ON(!qc); - - agg = &il->stations[sta_id].tid[tid].agg; - - il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx); - - /* check if BAR is needed */ - if ((tx_resp->frame_count == 1) && - !il4965_is_tx_success(status)) - info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - - if (txq->q.read_ptr != (scd_ssn & 0xff)) { - idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); - D_TX_REPLY("Retry scheduler reclaim scd_ssn " - "%d idx %d\n", scd_ssn, idx); - freed = il4965_tx_queue_reclaim(il, txq_id, idx); - if (qc) - il4965_free_tfds_in_queue(il, sta_id, tid, - freed); - - if (il->mac80211_registered && - il_queue_space(&txq->q) > txq->q.low_mark && - agg->state != IL_EMPTYING_HW_QUEUE_DELBA) - il_wake_queue(il, txq); - } - } else { - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags |= il4965_tx_status_to_mac80211(status); - il4965_hwrate_to_tx_control(il, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - D_TX_REPLY("TXQ %d status %s (0x%08x) " - "rate_n_flags 0x%x retries %d\n", txq_id, - il4965_get_tx_fail_reason(status), status, - le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - - freed = il4965_tx_queue_reclaim(il, txq_id, idx); - if (qc && likely(sta_id != IL_INVALID_STATION)) - il4965_free_tfds_in_queue(il, sta_id, tid, freed); - else if (sta_id == IL_INVALID_STATION) - D_TX_REPLY("Station not known\n"); - - if (il->mac80211_registered && - il_queue_space(&txq->q) > txq->q.low_mark) - il_wake_queue(il, txq); - } - if (qc && likely(sta_id != IL_INVALID_STATION)) - il4965_txq_check_empty(il, sta_id, tid, txq_id); - - il4965_check_abort_status(il, tx_resp->frame_count, status); - - spin_unlock_irqrestore(&il->sta_lock, flags); -} - -/* Set up 4965-specific Rx frame reply handlers */ -static void -il4965_handler_setup(struct il_priv *il) -{ - /* Legacy Rx frames */ - il->handlers[N_RX] = il4965_hdl_rx; - /* Tx response */ - il->handlers[C_TX] = il4965_hdl_tx; -} - -static struct il_hcmd_ops il4965_hcmd = { - .rxon_assoc = il4965_send_rxon_assoc, - .commit_rxon = il4965_commit_rxon, - .set_rxon_chain = il4965_set_rxon_chain, -}; - static void il4965_post_scan(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - /* * Since setting the RXON may have been deferred while * performing the scan, fire one off if needed */ - if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) - il_commit_rxon(il, ctx); + if (memcmp(&il->staging, &il->active, sizeof(il->staging))) + il_commit_rxon(il); } static void il4965_post_associate(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; struct ieee80211_conf *conf = NULL; int ret = 0; @@ -2161,41 +1761,41 @@ il4965_post_associate(struct il_priv *il) conf = &il->hw->conf; - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il_commit_rxon(il); - ret = il_send_rxon_timing(il, ctx); + ret = il_send_rxon_timing(il); if (ret) IL_WARN("RXON timing - " "Attempting to continue.\n"); - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; il_set_rxon_ht(il, &il->current_ht_config); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); - ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); + il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - il_commit_rxon(il, ctx); + il_commit_rxon(il); D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid, - ctx->active.bssid_addr); + il->active.bssid_addr); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -2223,8 +1823,7 @@ il4965_post_associate(struct il_priv *il) static void il4965_config_ap(struct il_priv *il) { - struct il_rxon_context *ctx = &il->ctx; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; int ret = 0; lockdep_assert_held(&il->mutex); @@ -2233,14 +1832,14 @@ il4965_config_ap(struct il_priv *il) return; /* The following should be done only at AP bring up */ - if (!il_is_associated_ctx(ctx)) { + if (!il_is_associated(il)) { /* RXON - unassoc (to set timing command) */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il_commit_rxon(il); /* RXON Timing */ - ret = il_send_rxon_timing(il, ctx); + ret = il_send_rxon_timing(il); if (ret) IL_WARN("RXON timing failed - " "Attempting to continue.\n"); @@ -2248,133 +1847,63 @@ il4965_config_ap(struct il_priv *il) /* AP has all antennas */ il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant; il_set_rxon_ht(il, &il->current_ht_config); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); - ctx->staging.assoc_id = 0; + il->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* need to send beacon cmd before committing assoc RXON! */ il4965_send_beacon_cmd(il); /* restore RXON assoc */ - ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + il_commit_rxon(il); } il4965_send_beacon_cmd(il); } -static struct il_hcmd_utils_ops il4965_hcmd_utils = { - .get_hcmd_size = il4965_get_hcmd_size, - .build_addsta_hcmd = il4965_build_addsta_hcmd, - .request_scan = il4965_request_scan, - .post_scan = il4965_post_scan, -}; - -static struct il_lib_ops il4965_lib = { - .set_hw_params = il4965_hw_set_hw_params, +const struct il_ops il4965_ops = { .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl, .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd, .txq_free_tfd = il4965_hw_txq_free_tfd, .txq_init = il4965_hw_tx_queue_init, - .handler_setup = il4965_handler_setup, .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr, .init_alive_start = il4965_init_alive_start, .load_ucode = il4965_load_bsm, .dump_nic_error_log = il4965_dump_nic_error_log, .dump_fh = il4965_dump_fh, .set_channel_switch = il4965_hw_channel_switch, - .apm_ops = { - .init = il_apm_init, - .config = il4965_nic_config, - }, - .eeprom_ops = { - .regulatory_bands = { - EEPROM_REGULATORY_BAND_1_CHANNELS, - EEPROM_REGULATORY_BAND_2_CHANNELS, - EEPROM_REGULATORY_BAND_3_CHANNELS, - EEPROM_REGULATORY_BAND_4_CHANNELS, - EEPROM_REGULATORY_BAND_5_CHANNELS, - EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, - EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS}, - .acquire_semaphore = il4965_eeprom_acquire_semaphore, - .release_semaphore = il4965_eeprom_release_semaphore, - }, + .apm_init = il_apm_init, .send_tx_power = il4965_send_tx_power, .update_chain_flags = il4965_update_chain_flags, - .temp_ops = { - .temperature = il4965_temperature_calib, - }, -#ifdef CONFIG_IWLEGACY_DEBUGFS - .debugfs_ops = { - .rx_stats_read = il4965_ucode_rx_stats_read, - .tx_stats_read = il4965_ucode_tx_stats_read, - .general_stats_read = il4965_ucode_general_stats_read, - }, -#endif -}; + .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore, + .eeprom_release_semaphore = il4965_eeprom_release_semaphore, + + .rxon_assoc = il4965_send_rxon_assoc, + .commit_rxon = il4965_commit_rxon, + .set_rxon_chain = il4965_set_rxon_chain, + + .get_hcmd_size = il4965_get_hcmd_size, + .build_addsta_hcmd = il4965_build_addsta_hcmd, + .request_scan = il4965_request_scan, + .post_scan = il4965_post_scan, -static const struct il_legacy_ops il4965_legacy_ops = { .post_associate = il4965_post_associate, .config_ap = il4965_config_ap, .manage_ibss_station = il4965_manage_ibss_station, .update_bcast_stations = il4965_update_bcast_stations, -}; -struct ieee80211_ops il4965_hw_ops = { - .tx = il4965_mac_tx, - .start = il4965_mac_start, - .stop = il4965_mac_stop, - .add_interface = il_mac_add_interface, - .remove_interface = il_mac_remove_interface, - .change_interface = il_mac_change_interface, - .config = il_mac_config, - .configure_filter = il4965_configure_filter, - .set_key = il4965_mac_set_key, - .update_tkip_key = il4965_mac_update_tkip_key, - .conf_tx = il_mac_conf_tx, - .reset_tsf = il_mac_reset_tsf, - .bss_info_changed = il_mac_bss_info_changed, - .ampdu_action = il4965_mac_ampdu_action, - .hw_scan = il_mac_hw_scan, - .sta_add = il4965_mac_sta_add, - .sta_remove = il_mac_sta_remove, - .channel_switch = il4965_mac_channel_switch, - .tx_last_beacon = il_mac_tx_last_beacon, -}; - -static const struct il_ops il4965_ops = { - .lib = &il4965_lib, - .hcmd = &il4965_hcmd, - .utils = &il4965_hcmd_utils, - .led = &il4965_led_ops, - .legacy = &il4965_legacy_ops, - .ieee80211_ops = &il4965_hw_ops, -}; - -static struct il_base_params il4965_base_params = { - .eeprom_size = IL4965_EEPROM_IMG_SIZE, - .num_of_queues = IL49_NUM_QUEUES, - .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = true, - .led_compensation = 61, - .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS, - .wd_timeout = IL_DEF_WD_TIMEOUT, - .temperature_kelvin = true, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .send_led_cmd = il4965_send_led_cmd, }; struct il_cfg il4965_cfg = { @@ -2387,15 +1916,38 @@ struct il_cfg il4965_cfg = { .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, - .ops = &il4965_ops, .mod_params = &il4965_mod_params, - .base_params = &il4965_base_params, .led_mode = IL_LED_BLINK, /* * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. */ .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC, + + .eeprom_size = IL4965_EEPROM_IMG_SIZE, + .num_of_queues = IL49_NUM_QUEUES, + .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES, + .pll_cfg_val = 0, + .set_l0s = true, + .use_bsm = true, + .led_compensation = 61, + .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS, + .wd_timeout = IL_DEF_WD_TIMEOUT, + .temperature_kelvin = true, + .ucode_tracing = true, + .sensitivity_calib_by_driver = true, + .chain_noise_calib_by_driver = true, + + .regulatory_bands = { + EEPROM_REGULATORY_BAND_1_CHANNELS, + EEPROM_REGULATORY_BAND_2_CHANNELS, + EEPROM_REGULATORY_BAND_3_CHANNELS, + EEPROM_REGULATORY_BAND_4_CHANNELS, + EEPROM_REGULATORY_BAND_5_CHANNELS, + EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, + EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS + }, + }; /* Module firmware */ diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index f280e0161b1..1db677689cf 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -38,17 +38,16 @@ struct il_rxon_context; /* configuration for the _4965 devices */ extern struct il_cfg il4965_cfg; +extern const struct il_ops il4965_ops; extern struct il_mod_params il4965_mod_params; -extern struct ieee80211_ops il4965_hw_ops; - /* tx queue */ void il4965_free_tfds_in_queue(struct il_priv *il, int sta_id, int tid, int freed); /* RXON */ -void il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx); +void il4965_set_rxon_chain(struct il_priv *il); /* uCode */ int il4965_verify_ucode(struct il_priv *il); @@ -61,6 +60,8 @@ int il4965_rx_init(struct il_priv *il, struct il_rx_queue *rxq); int il4965_hw_nic_init(struct il_priv *il); int il4965_dump_fh(struct il_priv *il, char **buf, bool display); +void il4965_nic_config(struct il_priv *il); + /* rx */ void il4965_rx_queue_restock(struct il_priv *il); void il4965_rx_replenish(struct il_priv *il); @@ -68,8 +69,6 @@ void il4965_rx_replenish_now(struct il_priv *il); void il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq); int il4965_rxq_stop(struct il_priv *il); int il4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); -void il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb); -void il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb); void il4965_rx_handle(struct il_priv *il); /* tx */ @@ -85,7 +84,6 @@ int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif, int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); int il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id); -void il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb); int il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx); void il4965_hw_txq_ctx_free(struct il_priv *il); int il4965_txq_ctx_alloc(struct il_priv *il); @@ -107,12 +105,6 @@ void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx); void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, int tx_fifo_id, int scd_retry); -/* rx */ -void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb); -bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt); -void il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); -void il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb); - /* scan */ int il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif); @@ -134,21 +126,18 @@ il4965_get_tx_fail_reason(u32 status) #endif /* station management */ -int il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx); -int il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, u8 *sta_id_r); +int il4965_alloc_bcast_station(struct il_priv *il); +int il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r); int il4965_remove_default_wep_key(struct il_priv *il, - struct il_rxon_context *ctx, struct ieee80211_key_conf *key); -int il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx, +int il4965_set_default_wep_key(struct il_priv *il, struct ieee80211_key_conf *key); -int il4965_restore_default_wep_keys(struct il_priv *il, - struct il_rxon_context *ctx); -int il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, +int il4965_restore_default_wep_keys(struct il_priv *il); +int il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *key, u8 sta_id); -int il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx, +int il4965_remove_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *key, u8 sta_id); -void il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx, +void il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf, struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); @@ -279,6 +268,7 @@ il4965_hw_valid_rtc_data_addr(u32 addr) ((t) < IL_TX_POWER_TEMPERATURE_MIN || \ (t) > IL_TX_POWER_TEMPERATURE_MAX) +extern void il4965_temperature_calib(struct il_priv *il); /********************* END TEMPERATURE ***************************************/ /********************* START TXPOWER *****************************************/ @@ -937,17 +927,10 @@ void il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp); void il4965_sensitivity_calibration(struct il_priv *il, void *resp); void il4965_init_sensitivity(struct il_priv *il); void il4965_reset_run_time_calib(struct il_priv *il); -void il4965_calib_free_results(struct il_priv *il); /* Debug */ #ifdef CONFIG_IWLEGACY_DEBUGFS -ssize_t il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -ssize_t il4965_ucode_general_stats_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos); +extern const struct il_debugfs_ops il4965_debugfs_ops; #endif /****************************/ diff --git a/drivers/net/wireless/iwlegacy/Kconfig b/drivers/net/wireless/iwlegacy/Kconfig index 05bd375cb84..fb919727b8b 100644 --- a/drivers/net/wireless/iwlegacy/Kconfig +++ b/drivers/net/wireless/iwlegacy/Kconfig @@ -6,45 +6,6 @@ config IWLEGACY select LEDS_TRIGGERS select MAC80211_LEDS -menu "Debugging Options" - depends on IWLEGACY - -config IWLEGACY_DEBUG - bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers" - depends on IWLEGACY - ---help--- - This option will enable debug tracing output for the iwlegacy - drivers. - - This will result in the kernel module being ~100k larger. You can - control which debug output is sent to the kernel log by setting the - value in - - /sys/class/net/wlan0/device/debug_level - - This entry will only exist if this option is enabled. - - To set a value, simply echo an 8-byte hex value to the same file: - - % echo 0x43fff > /sys/class/net/wlan0/device/debug_level - - You can find the list of debug mask values in: - drivers/net/wireless/iwlegacy/common.h - - If this is your first time using this driver, you should say Y here - as the debug information can assist others in helping you resolve - any problems you may encounter. - -config IWLEGACY_DEBUGFS - bool "iwlegacy (iwl 3945/4965) debugfs support" - depends on IWLEGACY && MAC80211_DEBUGFS - ---help--- - Enable creation of debugfs files for the iwlegacy drivers. This - is a low-impact option that allows getting insight into the - driver's state at runtime. - -endmenu - config IWL4965 tristate "Intel Wireless WiFi 4965AGN (iwl4965)" depends on PCI && MAC80211 @@ -98,3 +59,42 @@ config IWL3945 inserted in and removed from the running kernel whenever you want), say M here and read <file:Documentation/kbuild/modules.txt>. The module will be called iwl3945. + +menu "iwl3945 / iwl4965 Debugging Options" + depends on IWLEGACY + +config IWLEGACY_DEBUG + bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers" + depends on IWLEGACY + ---help--- + This option will enable debug tracing output for the iwlegacy + drivers. + + This will result in the kernel module being ~100k larger. You can + control which debug output is sent to the kernel log by setting the + value in + + /sys/class/net/wlan0/device/debug_level + + This entry will only exist if this option is enabled. + + To set a value, simply echo an 8-byte hex value to the same file: + + % echo 0x43fff > /sys/class/net/wlan0/device/debug_level + + You can find the list of debug mask values in: + drivers/net/wireless/iwlegacy/common.h + + If this is your first time using this driver, you should say Y here + as the debug information can assist others in helping you resolve + any problems you may encounter. + +config IWLEGACY_DEBUGFS + bool "iwlegacy (iwl 3945/4965) debugfs support" + depends on IWLEGACY && MAC80211_DEBUGFS + ---help--- + Enable creation of debugfs files for the iwlegacy drivers. This + is a low-impact option that allows getting insight into the + driver's state at runtime. + +endmenu diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 36454d0bbee..e5ac04739bc 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -81,7 +81,7 @@ il_clear_bit(struct il_priv *p, u32 r, u32 m) } EXPORT_SYMBOL(il_clear_bit); -int +bool _il_grab_nic_access(struct il_priv *il) { int ret; @@ -111,14 +111,15 @@ _il_grab_nic_access(struct il_priv *il) _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); - if (ret < 0) { + if (unlikely(ret < 0)) { val = _il_rd(il, CSR_GP_CNTRL); - IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); + WARN_ONCE(1, "Timeout waiting for ucode processor access " + "(CSR_GP_CNTRL 0x%08x)\n", val); _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); - return -EIO; + return false; } - return 0; + return true; } EXPORT_SYMBOL_GPL(_il_grab_nic_access); @@ -160,7 +161,7 @@ il_wr_prph(struct il_priv *il, u32 addr, u32 val) unsigned long reg_flags; spin_lock_irqsave(&il->reg_lock, reg_flags); - if (!_il_grab_nic_access(il)) { + if (likely(_il_grab_nic_access(il))) { _il_wr_prph(il, addr, val); _il_release_nic_access(il); } @@ -178,7 +179,6 @@ il_read_targ_mem(struct il_priv *il, u32 addr) _il_grab_nic_access(il); _il_wr(il, HBUS_TARG_MEM_RADDR, addr); - rmb(); value = _il_rd(il, HBUS_TARG_MEM_RDAT); _il_release_nic_access(il); @@ -193,9 +193,8 @@ il_write_targ_mem(struct il_priv *il, u32 addr, u32 val) unsigned long reg_flags; spin_lock_irqsave(&il->reg_lock, reg_flags); - if (!_il_grab_nic_access(il)) { + if (likely(_il_grab_nic_access(il))) { _il_wr(il, HBUS_TARG_MEM_WADDR, addr); - wmb(); _il_wr(il, HBUS_TARG_MEM_WDAT, val); _il_release_nic_access(il); } @@ -351,7 +350,7 @@ il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd) } } - if (test_bit(S_RF_KILL_HW, &il->status)) { + if (test_bit(S_RFKILL, &il->status)) { IL_ERR("Command %s aborted: RF KILL Switch\n", il_get_cmd_string(cmd->id)); ret = -ECANCELED; @@ -512,15 +511,15 @@ il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off) } D_LED("Led blink time compensation=%u\n", - il->cfg->base_params->led_compensation); + il->cfg->led_compensation); led_cmd.on = il_blink_compensation(il, on, - il->cfg->base_params->led_compensation); + il->cfg->led_compensation); led_cmd.off = il_blink_compensation(il, off, - il->cfg->base_params->led_compensation); + il->cfg->led_compensation); - ret = il->cfg->ops->led->cmd(il, &led_cmd); + ret = il->ops->send_led_cmd(il, &led_cmd); if (!ret) { il->blink_on = on; il->blink_off = off; @@ -691,7 +690,7 @@ il_eeprom_verify_signature(struct il_priv *il) const u8 * il_eeprom_query_addr(const struct il_priv *il, size_t offset) { - BUG_ON(offset >= il->cfg->base_params->eeprom_size); + BUG_ON(offset >= il->cfg->eeprom_size); return &il->eeprom[offset]; } EXPORT_SYMBOL(il_eeprom_query_addr); @@ -722,7 +721,7 @@ il_eeprom_init(struct il_priv *il) u16 addr; /* allocate eeprom */ - sz = il->cfg->base_params->eeprom_size; + sz = il->cfg->eeprom_size; D_EEPROM("NVM size = %d\n", sz); il->eeprom = kzalloc(sz, GFP_KERNEL); if (!il->eeprom) { @@ -731,7 +730,7 @@ il_eeprom_init(struct il_priv *il) } e = (__le16 *) il->eeprom; - il->cfg->ops->lib->apm_ops.init(il); + il->ops->apm_init(il); ret = il_eeprom_verify_signature(il); if (ret < 0) { @@ -741,7 +740,7 @@ il_eeprom_init(struct il_priv *il) } /* Make sure driver (instead of uCode) is allowed to read EEPROM */ - ret = il->cfg->ops->lib->eeprom_ops.acquire_semaphore(il); + ret = il->ops->eeprom_acquire_semaphore(il); if (ret < 0) { IL_ERR("Failed to acquire EEPROM semaphore.\n"); ret = -ENOENT; @@ -773,7 +772,7 @@ il_eeprom_init(struct il_priv *il) ret = 0; done: - il->cfg->ops->lib->eeprom_ops.release_semaphore(il); + il->ops->eeprom_release_semaphore(il); err: if (ret) @@ -799,8 +798,8 @@ il_init_band_reference(const struct il_priv *il, int eep_band, const struct il_eeprom_channel **eeprom_ch_info, const u8 **eeprom_ch_idx) { - u32 offset = - il->cfg->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1]; + u32 offset = il->cfg->regulatory_bands[eep_band - 1]; + switch (eep_band) { case 1: /* 2.4GHz band */ *eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_1); @@ -1001,10 +1000,8 @@ il_init_channel_map(struct il_priv *il) } /* Check if we do have HT40 channels */ - if (il->cfg->ops->lib->eeprom_ops.regulatory_bands[5] == - EEPROM_REGULATORY_BAND_NO_HT40 && - il->cfg->ops->lib->eeprom_ops.regulatory_bands[6] == - EEPROM_REGULATORY_BAND_NO_HT40) + if (il->cfg->regulatory_bands[5] == EEPROM_REGULATORY_BAND_NO_HT40 && + il->cfg->regulatory_bands[6] == EEPROM_REGULATORY_BAND_NO_HT40) return 0; /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ @@ -1158,9 +1155,9 @@ il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force) if (!(cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK)) clear_bit(S_POWER_PMI, &il->status); - if (il->cfg->ops->lib->update_chain_flags && update_chains) - il->cfg->ops->lib->update_chain_flags(il); - else if (il->cfg->ops->lib->update_chain_flags) + if (il->ops->update_chain_flags && update_chains) + il->ops->update_chain_flags(il); + else if (il->ops->update_chain_flags) D_POWER("Cannot update the power, chain noise " "calibration running: %d\n", il->chain_noise_data.state); @@ -1442,7 +1439,6 @@ u16 il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band, struct ieee80211_vif *vif) { - struct il_rxon_context *ctx = &il->ctx; u16 value; u16 passive = @@ -1457,7 +1453,7 @@ il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band, * dwell time to be 98% of the smallest beacon interval * (minus 2 * channel tune time) */ - value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; + value = il->vif ? il->vif->bss_conf.beacon_int : 0; if (value > IL_PASSIVE_DWELL_BASE || !value) value = IL_PASSIVE_DWELL_BASE; value = (value * 98) / 100 - IL_CHANNEL_TUNE_TIME * 2; @@ -1486,9 +1482,6 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif) lockdep_assert_held(&il->mutex); - if (WARN_ON(!il->cfg->ops->utils->request_scan)) - return -EOPNOTSUPP; - cancel_delayed_work(&il->scan_check); if (!il_is_ready_rf(il)) { @@ -1511,7 +1504,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif) set_bit(S_SCANNING, &il->status); il->scan_start = jiffies; - ret = il->cfg->ops->utils->request_scan(il, vif); + ret = il->ops->request_scan(il, vif); if (ret) { clear_bit(S_SCANNING, &il->status); return ret; @@ -1530,12 +1523,13 @@ il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct il_priv *il = hw->priv; int ret; - D_MAC80211("enter\n"); - - if (req->n_channels == 0) + if (req->n_channels == 0) { + IL_ERR("Can not scan on no channels.\n"); return -EINVAL; + } mutex_lock(&il->mutex); + D_MAC80211("enter\n"); if (test_bit(S_SCANNING, &il->status)) { D_SCAN("Scan already in progress.\n"); @@ -1550,9 +1544,8 @@ il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ret = il_scan_initiate(il, vif); - D_MAC80211("leave\n"); - out_unlock: + D_MAC80211("leave ret %d\n", ret); mutex_unlock(&il->mutex); return ret; @@ -1673,7 +1666,7 @@ out_settings: il_power_set_mode(il, &il->power_data.sleep_cmd_next, false); il_set_tx_power(il, il->tx_power_next, false); - il->cfg->ops->utils->post_scan(il); + il->ops->post_scan(il); out: mutex_unlock(&il->mutex); @@ -1815,7 +1808,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags) might_sleep(); } - cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data); + cmd.len = il->ops->build_addsta_hcmd(sta, data); ret = il_send_cmd(il, &cmd); if (ret || (flags & CMD_ASYNC)) @@ -1832,8 +1825,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags) EXPORT_SYMBOL(il_send_add_sta); static void -il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta, - struct il_rxon_context *ctx) +il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta) { struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; __le32 sta_flags; @@ -1874,7 +1866,7 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta, cpu_to_le32((u32) sta_ht_inf-> ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap)) + if (il_is_ht40_tx_allowed(il, &sta->ht_cap)) sta_flags |= STA_FLG_HT40_EN_MSK; else sta_flags &= ~STA_FLG_HT40_EN_MSK; @@ -1890,8 +1882,8 @@ done: * should be called with sta_lock held */ u8 -il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta) +il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, + struct ieee80211_sta *sta) { struct il_station_entry *station; int i; @@ -1899,9 +1891,9 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, u16 rate; if (is_ap) - sta_id = ctx->ap_sta_id; + sta_id = IL_AP_ID; else if (is_broadcast_ether_addr(addr)) - sta_id = ctx->bcast_sta_id; + sta_id = il->hw_params.bcast_id; else for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) { if (!compare_ether_addr @@ -1950,22 +1942,14 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = sta_id; - station->sta.station_flags = ctx->station_flags; - station->ctxid = ctx->ctxid; - - if (sta) { - struct il_station_priv_common *sta_priv; - - sta_priv = (void *)sta->drv_priv; - sta_priv->ctx = ctx; - } + station->sta.station_flags = 0; /* * OK to call unconditionally, since local stations (IBSS BSSID * STA and broadcast STA) pass in a NULL sta, and mac80211 * doesn't allow HT IBSS. */ - il_set_ht_add_station(il, sta_id, sta, ctx); + il_set_ht_add_station(il, sta_id, sta); /* 3945 only */ rate = (il->band == IEEE80211_BAND_5GHZ) ? RATE_6M_PLCP : RATE_1M_PLCP; @@ -1983,9 +1967,8 @@ EXPORT_SYMBOL_GPL(il_prep_station); * il_add_station_common - */ int -il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta, - u8 *sta_id_r) +il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap, + struct ieee80211_sta *sta, u8 *sta_id_r) { unsigned long flags_spin; int ret = 0; @@ -1994,7 +1977,7 @@ il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx, *sta_id_r = 0; spin_lock_irqsave(&il->sta_lock, flags_spin); - sta_id = il_prep_station(il, ctx, addr, is_ap, sta); + sta_id = il_prep_station(il, addr, is_ap, sta); if (sta_id == IL_INVALID_STATION) { IL_ERR("Unable to prepare station %pM for addition\n", addr); spin_unlock_irqrestore(&il->sta_lock, flags_spin); @@ -2181,7 +2164,7 @@ EXPORT_SYMBOL_GPL(il_remove_station); * the ucode, e.g. unassociated RXON. */ void -il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx) +il_clear_ucode_stations(struct il_priv *il) { int i; unsigned long flags_spin; @@ -2191,9 +2174,6 @@ il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx) spin_lock_irqsave(&il->sta_lock, flags_spin); for (i = 0; i < il->hw_params.max_stations; i++) { - if (ctx && ctx->ctxid != il->stations[i].ctxid) - continue; - if (il->stations[i].used & IL_STA_UCODE_ACTIVE) { D_INFO("Clearing ucode active for station %d\n", i); il->stations[i].used &= ~IL_STA_UCODE_ACTIVE; @@ -2216,7 +2196,7 @@ EXPORT_SYMBOL(il_clear_ucode_stations); * Function sleeps. */ void -il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) +il_restore_stations(struct il_priv *il) { struct il_addsta_cmd sta_cmd; struct il_link_quality_cmd lq; @@ -2234,8 +2214,6 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) D_ASSOC("Restoring all known stations ... start.\n"); spin_lock_irqsave(&il->sta_lock, flags_spin); for (i = 0; i < il->hw_params.max_stations; i++) { - if (ctx->ctxid != il->stations[i].ctxid) - continue; if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) && !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) { D_ASSOC("Restoring sta %pM\n", @@ -2273,7 +2251,7 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx) * current LQ command */ if (send_lq) - il_send_lq_cmd(il, ctx, &lq, CMD_SYNC, true); + il_send_lq_cmd(il, &lq, CMD_SYNC, true); spin_lock_irqsave(&il->sta_lock, flags_spin); il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS; } @@ -2353,15 +2331,14 @@ il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq) * RXON flags are updated and when LQ command is updated. */ static bool -il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq) +il_is_lq_table_valid(struct il_priv *il, struct il_link_quality_cmd *lq) { int i; - if (ctx->ht.enabled) + if (il->ht.enabled) return true; - D_INFO("Channel %u is not an HT channel\n", ctx->active.channel); + D_INFO("Channel %u is not an HT channel\n", il->active.channel); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { D_INFO("idx %d of LQ expects HT channel\n", i); @@ -2382,8 +2359,8 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx, * progress. */ int -il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq, u8 flags, bool init) +il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq, + u8 flags, bool init) { int ret = 0; unsigned long flags_spin; @@ -2408,7 +2385,7 @@ il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, il_dump_lq_cmd(il, lq); BUG_ON(init && (cmd.flags & CMD_ASYNC)); - if (il_is_lq_table_valid(il, ctx, lq)) + if (il_is_lq_table_valid(il, lq)) ret = il_send_cmd(il, &cmd); else ret = -EINVAL; @@ -2436,13 +2413,16 @@ il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct il_station_priv_common *sta_common = (void *)sta->drv_priv; int ret; - D_INFO("received request to remove station %pM\n", sta->addr); mutex_lock(&il->mutex); - D_INFO("proceeding to remove station %pM\n", sta->addr); + D_MAC80211("enter station %pM\n", sta->addr); + ret = il_remove_station(il, sta_common->sta_id, sta->addr); if (ret) IL_ERR("Error removing station %pM\n", sta->addr); + + D_MAC80211("leave ret %d\n", ret); mutex_unlock(&il->mutex); + return ret; } EXPORT_SYMBOL(il_mac_sta_remove); @@ -2648,7 +2628,7 @@ il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr, * All contexts have the same setting here due to it being * a module parameter, so OK to check any context. */ - if (il->ctx.active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) + if (il->active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) return 0; if (!(fc & IEEE80211_FCTL_PROTECTED)) @@ -2739,7 +2719,7 @@ il_tx_queue_unmap(struct il_priv *il, int txq_id) return; while (q->write_ptr != q->read_ptr) { - il->cfg->ops->lib->txq_free_tfd(il, txq); + il->ops->txq_free_tfd(il, txq); q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd); } } @@ -2772,8 +2752,8 @@ il_tx_queue_free(struct il_priv *il, int txq_id) txq->tfds, txq->q.dma_addr); /* De-alloc array of per-TFD driver data */ - kfree(txq->txb); - txq->txb = NULL; + kfree(txq->skbs); + txq->skbs = NULL; /* deallocate arrays */ kfree(txq->cmd); @@ -2907,20 +2887,22 @@ EXPORT_SYMBOL(il_queue_space); * il_queue_init - Initialize queue's high/low-water and read/write idxes */ static int -il_queue_init(struct il_priv *il, struct il_queue *q, int count, int slots_num, - u32 id) +il_queue_init(struct il_priv *il, struct il_queue *q, int slots, u32 id) { - q->n_bd = count; - q->n_win = slots_num; - q->id = id; + /* + * TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise + * il_queue_inc_wrap and il_queue_dec_wrap are broken. + */ + BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); + /* FIXME: remove q->n_bd */ + q->n_bd = TFD_QUEUE_SIZE_MAX; - /* count must be power-of-two size, otherwise il_queue_inc_wrap - * and il_queue_dec_wrap are broken. */ - BUG_ON(!is_power_of_2(count)); + q->n_win = slots; + q->id = id; - /* slots_num must be power-of-two size, otherwise + /* slots_must be power-of-two size, otherwise * il_get_cmd_idx is broken. */ - BUG_ON(!is_power_of_2(slots_num)); + BUG_ON(!is_power_of_2(slots)); q->low_mark = q->n_win / 4; if (q->low_mark < 4) @@ -2947,23 +2929,21 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) /* Driver ilate data, only for Tx (not command) queues, * not shared with device. */ if (id != il->cmd_queue) { - txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]), - GFP_KERNEL); - if (!txq->txb) { - IL_ERR("kmalloc for auxiliary BD " - "structures failed\n"); + txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(struct skb *), + GFP_KERNEL); + if (!txq->skbs) { + IL_ERR("Fail to alloc skbs\n"); goto error; } - } else { - txq->txb = NULL; - } + } else + txq->skbs = NULL; /* Circular buffer of transmit frame descriptors (TFDs), * shared with device */ txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { - IL_ERR("pci_alloc_consistent(%zd) failed\n", tfd_sz); + IL_ERR("Fail to alloc TFDs\n"); goto error; } txq->q.id = id; @@ -2971,8 +2951,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) return 0; error: - kfree(txq->txb); - txq->txb = NULL; + kfree(txq->skbs); + txq->skbs = NULL; return -ENOMEM; } @@ -2981,12 +2961,11 @@ error: * il_tx_queue_init - Allocate and initialize one tx/cmd queue */ int -il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, - u32 txq_id) +il_tx_queue_init(struct il_priv *il, u32 txq_id) { - int i, len; - int ret; - int actual_slots = slots_num; + int i, len, ret; + int slots, actual_slots; + struct il_tx_queue *txq = &il->txq[txq_id]; /* * Alloc buffer array for commands (Tx or other types of commands). @@ -2996,8 +2975,13 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, * For normal Tx queues (all other queues), no super-size command * space is needed. */ - if (txq_id == il->cmd_queue) - actual_slots++; + if (txq_id == il->cmd_queue) { + slots = TFD_CMD_SLOTS; + actual_slots = slots + 1; + } else { + slots = TFD_TX_CMD_SLOTS; + actual_slots = slots; + } txq->meta = kzalloc(sizeof(struct il_cmd_meta) * actual_slots, GFP_KERNEL); @@ -3010,7 +2994,7 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, len = sizeof(struct il_device_cmd); for (i = 0; i < actual_slots; i++) { /* only happens for cmd queue */ - if (i == slots_num) + if (i == slots) len = IL_MAX_CMD_SIZE; txq->cmd[i] = kmalloc(len, GFP_KERNEL); @@ -3033,15 +3017,11 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, if (txq_id < 4) il_set_swq_id(txq, txq_id, txq_id); - /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise - * il_queue_inc_wrap and il_queue_dec_wrap are broken. */ - BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); - /* Initialize queue's high/low-water marks, and head/tail idxes */ - il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + il_queue_init(il, &txq->q, slots, txq_id); /* Tell device where to find queue */ - il->cfg->ops->lib->txq_init(il, txq); + il->ops->txq_init(il, txq); return 0; err: @@ -3056,23 +3036,27 @@ out_free_arrays: EXPORT_SYMBOL(il_tx_queue_init); void -il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, int slots_num, - u32 txq_id) +il_tx_queue_reset(struct il_priv *il, u32 txq_id) { - int actual_slots = slots_num; + int slots, actual_slots; + struct il_tx_queue *txq = &il->txq[txq_id]; - if (txq_id == il->cmd_queue) - actual_slots++; + if (txq_id == il->cmd_queue) { + slots = TFD_CMD_SLOTS; + actual_slots = TFD_CMD_SLOTS + 1; + } else { + slots = TFD_TX_CMD_SLOTS; + actual_slots = TFD_TX_CMD_SLOTS; + } memset(txq->meta, 0, sizeof(struct il_cmd_meta) * actual_slots); - txq->need_update = 0; /* Initialize queue's high/low-water marks, and head/tail idxes */ - il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + il_queue_init(il, &txq->q, slots, txq_id); /* Tell device where to find queue */ - il->cfg->ops->lib->txq_init(il, txq); + il->ops->txq_init(il, txq); } EXPORT_SYMBOL(il_tx_queue_reset); @@ -3100,7 +3084,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) u32 idx; u16 fix_size; - cmd->len = il->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); + cmd->len = il->ops->get_hcmd_size(cmd->id, cmd->len); fix_size = (u16) (cmd->len + sizeof(out_cmd->hdr)); /* If any of the command structures end up being larger than @@ -3179,9 +3163,9 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) #endif txq->need_update = 1; - if (il->cfg->ops->lib->txq_update_byte_cnt_tbl) + if (il->ops->txq_update_byte_cnt_tbl) /* Set up entry in queue's byte count circular buffer */ - il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0); + il->ops->txq_update_byte_cnt_tbl(il, txq, 0); phys_addr = pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size, @@ -3189,8 +3173,8 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) dma_unmap_addr_set(out_meta, mapping, phys_addr); dma_unmap_len_set(out_meta, len, fix_size); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, - 1, U32_PAD(cmd->len)); + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1, + U32_PAD(cmd->len)); /* Increment and update queue's write idx */ q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd); @@ -3332,30 +3316,6 @@ EXPORT_SYMBOL(il_debug_level); const u8 il_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; EXPORT_SYMBOL(il_bcast_addr); -/* This function both allocates and initializes hw and il. */ -struct ieee80211_hw * -il_alloc_all(struct il_cfg *cfg) -{ - struct il_priv *il; - /* mac80211 allocates memory for this device instance, including - * space for this driver's ilate structure */ - struct ieee80211_hw *hw; - - hw = ieee80211_alloc_hw(sizeof(struct il_priv), - cfg->ops->ieee80211_ops); - if (hw == NULL) { - pr_err("%s: Can not allocate network device\n", cfg->name); - goto out; - } - - il = hw->priv; - il->hw = hw; - -out: - return hw; -} -EXPORT_SYMBOL(il_alloc_all); - #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ static void @@ -3562,10 +3522,9 @@ il_is_channel_extension(struct il_priv *il, enum ieee80211_band band, } bool -il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, - struct ieee80211_sta_ht_cap *ht_cap) +il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap) { - if (!ctx->ht.enabled || !ctx->ht.is_40mhz) + if (!il->ht.enabled || !il->ht.is_40mhz) return false; /* @@ -3581,8 +3540,8 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, #endif return il_is_channel_extension(il, il->band, - le16_to_cpu(ctx->staging.channel), - ctx->ht.extension_chan_offset); + le16_to_cpu(il->staging.channel), + il->ht.extension_chan_offset); } EXPORT_SYMBOL(il_is_ht40_tx_allowed); @@ -3621,22 +3580,22 @@ il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) } int -il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) +il_send_rxon_timing(struct il_priv *il) { u64 tsf; s32 interval_tm, rem; struct ieee80211_conf *conf = NULL; u16 beacon_int; - struct ieee80211_vif *vif = ctx->vif; + struct ieee80211_vif *vif = il->vif; conf = &il->hw->conf; lockdep_assert_held(&il->mutex); - memset(&ctx->timing, 0, sizeof(struct il_rxon_time_cmd)); + memset(&il->timing, 0, sizeof(struct il_rxon_time_cmd)); - ctx->timing.timestamp = cpu_to_le64(il->timestamp); - ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); + il->timing.timestamp = cpu_to_le64(il->timestamp); + il->timing.listen_interval = cpu_to_le16(conf->listen_interval); beacon_int = vif ? vif->bss_conf.beacon_int : 0; @@ -3644,36 +3603,35 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx) * TODO: For IBSS we need to get atim_win from mac80211, * for now just always use 0 */ - ctx->timing.atim_win = 0; + il->timing.atim_win = 0; beacon_int = il_adjust_beacon_interval(beacon_int, il->hw_params.max_beacon_itrvl * TIME_UNIT); - ctx->timing.beacon_interval = cpu_to_le16(beacon_int); + il->timing.beacon_interval = cpu_to_le16(beacon_int); tsf = il->timestamp; /* tsf is modifed by do_div: copy it */ interval_tm = beacon_int * TIME_UNIT; rem = do_div(tsf, interval_tm); - ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + il->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); - ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1; + il->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1; D_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n", - le16_to_cpu(ctx->timing.beacon_interval), - le32_to_cpu(ctx->timing.beacon_init_val), - le16_to_cpu(ctx->timing.atim_win)); + le16_to_cpu(il->timing.beacon_interval), + le32_to_cpu(il->timing.beacon_init_val), + le16_to_cpu(il->timing.atim_win)); - return il_send_cmd_pdu(il, ctx->rxon_timing_cmd, sizeof(ctx->timing), - &ctx->timing); + return il_send_cmd_pdu(il, C_RXON_TIMING, sizeof(il->timing), + &il->timing); } EXPORT_SYMBOL(il_send_rxon_timing); void -il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx, - int hw_decrypt) +il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; if (hw_decrypt) rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; @@ -3685,9 +3643,9 @@ EXPORT_SYMBOL(il_set_rxon_hwcrypto); /* validate RXON structure is valid */ int -il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx) +il_check_rxon_cmd(struct il_priv *il) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; bool error = false; if (rxon->flags & RXON_FLG_BAND_24G_MSK) { @@ -3765,10 +3723,10 @@ EXPORT_SYMBOL(il_check_rxon_cmd); * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ int -il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) +il_full_rxon_required(struct il_priv *il) { - const struct il_rxon_cmd *staging = &ctx->staging; - const struct il_rxon_cmd *active = &ctx->active; + const struct il_rxon_cmd *staging = &il->staging; + const struct il_rxon_cmd *active = &il->active; #define CHK(cond) \ if ((cond)) { \ @@ -3785,7 +3743,7 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) } /* These items are only settable from the full RXON command */ - CHK(!il_is_associated_ctx(ctx)); + CHK(!il_is_associated(il)); CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); CHK(compare_ether_addr(staging->node_addr, active->node_addr)); CHK(compare_ether_addr @@ -3819,13 +3777,13 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx) EXPORT_SYMBOL(il_full_rxon_required); u8 -il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx) +il_get_lowest_plcp(struct il_priv *il) { /* * Assign the lowest rate -- should really get this from * the beacon skb from mac80211. */ - if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) + if (il->staging.flags & RXON_FLG_BAND_24G_MSK) return RATE_1M_PLCP; else return RATE_6M_PLCP; @@ -3833,12 +3791,11 @@ il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx) EXPORT_SYMBOL(il_get_lowest_plcp); static void -_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, - struct il_rxon_context *ctx) +_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; - if (!ctx->ht.enabled) { + if (!il->ht.enabled) { rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK @@ -3847,19 +3804,19 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, } rxon->flags |= - cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); + cpu_to_le32(il->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); /* Set up channel bandwidth: * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ /* clear the HT channel mode before set the mode */ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); - if (il_is_ht40_tx_allowed(il, ctx, NULL)) { + if (il_is_ht40_tx_allowed(il, NULL)) { /* pure ht40 */ - if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { + if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; /* Note: control channel is opposite of extension channel */ - switch (ctx->ht.extension_chan_offset) { + switch (il->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; @@ -3870,7 +3827,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, } } else { /* Note: control channel is opposite of extension channel */ - switch (ctx->ht.extension_chan_offset) { + switch (il->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); @@ -3891,18 +3848,18 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf, rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY; } - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); D_ASSOC("rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", le32_to_cpu(rxon->flags), - ctx->ht.protection, ctx->ht.extension_chan_offset); + il->ht.protection, il->ht.extension_chan_offset); } void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf) { - _il_set_rxon_ht(il, ht_conf, &il->ctx); + _il_set_rxon_ht(il, ht_conf); } EXPORT_SYMBOL(il_set_rxon_ht); @@ -3925,7 +3882,7 @@ il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band) for (i = min; i < max; i++) { channel = il->channel_info[i].channel; - if (channel == le16_to_cpu(il->ctx.staging.channel)) + if (channel == le16_to_cpu(il->staging.channel)) continue; ch_info = il_get_channel_info(il, band, channel); @@ -3945,20 +3902,19 @@ EXPORT_SYMBOL(il_get_single_channel_number); * in the staging RXON flag structure based on the ch->band */ int -il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, - struct il_rxon_context *ctx) +il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch) { enum ieee80211_band band = ch->band; u16 channel = ch->hw_value; - if (le16_to_cpu(ctx->staging.channel) == channel && il->band == band) + if (le16_to_cpu(il->staging.channel) == channel && il->band == band) return 0; - ctx->staging.channel = cpu_to_le16(channel); + il->staging.channel = cpu_to_le16(channel); if (band == IEEE80211_BAND_5GHZ) - ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; + il->staging.flags &= ~RXON_FLG_BAND_24G_MSK; else - ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; + il->staging.flags |= RXON_FLG_BAND_24G_MSK; il->band = band; @@ -3969,24 +3925,24 @@ il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, EXPORT_SYMBOL(il_set_rxon_channel); void -il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx, - enum ieee80211_band band, struct ieee80211_vif *vif) +il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band, + struct ieee80211_vif *vif) { if (band == IEEE80211_BAND_5GHZ) { - ctx->staging.flags &= + il->staging.flags &= ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_CCK_MSK); - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { /* Copied from il_post_associate() */ if (vif && vif->bss_conf.use_short_slot) - ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; - ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; - ctx->staging.flags &= ~RXON_FLG_CCK_MSK; + il->staging.flags |= RXON_FLG_BAND_24G_MSK; + il->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; + il->staging.flags &= ~RXON_FLG_CCK_MSK; } } EXPORT_SYMBOL(il_set_flags_for_band); @@ -3995,69 +3951,60 @@ EXPORT_SYMBOL(il_set_flags_for_band); * initialize rxon structure with default values from eeprom */ void -il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx) +il_connection_init_rx_config(struct il_priv *il) { const struct il_channel_info *ch_info; - memset(&ctx->staging, 0, sizeof(ctx->staging)); - - if (!ctx->vif) { - ctx->staging.dev_type = ctx->unused_devtype; - } else - switch (ctx->vif->type) { - - case NL80211_IFTYPE_STATION: - ctx->staging.dev_type = ctx->station_devtype; - ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; - break; - - case NL80211_IFTYPE_ADHOC: - ctx->staging.dev_type = ctx->ibss_devtype; - ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; - ctx->staging.filter_flags = - RXON_FILTER_BCON_AWARE_MSK | - RXON_FILTER_ACCEPT_GRP_MSK; - break; - - default: - IL_ERR("Unsupported interface type %d\n", - ctx->vif->type); - break; - } + memset(&il->staging, 0, sizeof(il->staging)); + + if (!il->vif) { + il->staging.dev_type = RXON_DEV_TYPE_ESS; + } else if (il->vif->type == NL80211_IFTYPE_STATION) { + il->staging.dev_type = RXON_DEV_TYPE_ESS; + il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + } else if (il->vif->type == NL80211_IFTYPE_ADHOC) { + il->staging.dev_type = RXON_DEV_TYPE_IBSS; + il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.filter_flags = + RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; + } else { + IL_ERR("Unsupported interface type %d\n", il->vif->type); + return; + } #if 0 /* TODO: Figure out when short_preamble would be set and cache from * that */ if (!hw_to_local(il->hw)->short_preamble) - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif ch_info = - il_get_channel_info(il, il->band, le16_to_cpu(ctx->active.channel)); + il_get_channel_info(il, il->band, le16_to_cpu(il->active.channel)); if (!ch_info) ch_info = &il->channel_info[0]; - ctx->staging.channel = cpu_to_le16(ch_info->channel); + il->staging.channel = cpu_to_le16(ch_info->channel); il->band = ch_info->band; - il_set_flags_for_band(il, ctx, il->band, ctx->vif); + il_set_flags_for_band(il, il->band, il->vif); - ctx->staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = (IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; - ctx->staging.cck_basic_rates = + il->staging.cck_basic_rates = (IL_CCK_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF; /* clear both MIX and PURE40 mode flag */ - ctx->staging.flags &= + il->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); - if (ctx->vif) - memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); + if (il->vif) + memcpy(il->staging.node_addr, il->vif->addr, ETH_ALEN); - ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; - ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; + il->staging.ofdm_ht_single_stream_basic_rates = 0xff; + il->staging.ofdm_ht_dual_stream_basic_rates = 0xff; } EXPORT_SYMBOL(il_connection_init_rx_config); @@ -4084,10 +4031,10 @@ il_set_rate(struct il_priv *il) D_RATE("Set active_rate = %0x\n", il->active_rate); - il->ctx.staging.cck_basic_rates = + il->staging.cck_basic_rates = (IL_CCK_BASIC_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF; - il->ctx.staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = (IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF; } EXPORT_SYMBOL(il_set_rate); @@ -4095,13 +4042,11 @@ EXPORT_SYMBOL(il_set_rate); void il_chswitch_done(struct il_priv *il, bool is_success) { - struct il_rxon_context *ctx = &il->ctx; - if (test_bit(S_EXIT_PENDING, &il->status)) return; if (test_and_clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) - ieee80211_chswitch_done(ctx->vif, is_success); + ieee80211_chswitch_done(il->vif, is_success); } EXPORT_SYMBOL(il_chswitch_done); @@ -4110,16 +4055,14 @@ il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb) { struct il_rx_pkt *pkt = rxb_addr(rxb); struct il_csa_notification *csa = &(pkt->u.csa_notif); - - struct il_rxon_context *ctx = &il->ctx; - struct il_rxon_cmd *rxon = (void *)&ctx->active; + struct il_rxon_cmd *rxon = (void *)&il->active; if (!test_bit(S_CHANNEL_SWITCH_PENDING, &il->status)) return; if (!le32_to_cpu(csa->status) && csa->channel == il->switch_channel) { rxon->channel = csa->channel; - ctx->staging.channel = csa->channel; + il->staging.channel = csa->channel; D_11H("CSA notif: channel %d\n", le16_to_cpu(csa->channel)); il_chswitch_done(il, true); } else { @@ -4132,9 +4075,9 @@ EXPORT_SYMBOL(il_hdl_csa); #ifdef CONFIG_IWLEGACY_DEBUG void -il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx) +il_print_rx_config_cmd(struct il_priv *il) { - struct il_rxon_cmd *rxon = &ctx->staging; + struct il_rxon_cmd *rxon = &il->staging; D_RADIO("RX CONFIG:\n"); il_print_hex_dump(il, IL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); @@ -4164,12 +4107,12 @@ il_irq_handle_error(struct il_priv *il) IL_ERR("Loaded firmware version: %s\n", il->hw->wiphy->fw_version); - il->cfg->ops->lib->dump_nic_error_log(il); - if (il->cfg->ops->lib->dump_fh) - il->cfg->ops->lib->dump_fh(il, NULL, false); + il->ops->dump_nic_error_log(il); + if (il->ops->dump_fh) + il->ops->dump_fh(il, NULL, false); #ifdef CONFIG_IWLEGACY_DEBUG if (il_get_debug_level(il) & IL_DL_FW_ERRORS) - il_print_rx_config_cmd(il, &il->ctx); + il_print_rx_config_cmd(il); #endif wake_up(&il->wait_command_queue); @@ -4189,17 +4132,17 @@ il_irq_handle_error(struct il_priv *il) EXPORT_SYMBOL(il_irq_handle_error); static int -il_apm_stop_master(struct il_priv *il) +_il_apm_stop_master(struct il_priv *il) { int ret = 0; /* stop device's busmaster DMA activity */ - il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); ret = _il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); - if (ret) + if (ret < 0) IL_WARN("Master Disable Timed Out, 100 usec\n"); D_INFO("stop master\n"); @@ -4208,15 +4151,17 @@ il_apm_stop_master(struct il_priv *il) } void -il_apm_stop(struct il_priv *il) +_il_apm_stop(struct il_priv *il) { + lockdep_assert_held(&il->reg_lock); + D_INFO("Stop card, put in low power state\n"); /* Stop device's DMA activity */ - il_apm_stop_master(il); + _il_apm_stop_master(il); /* Reset the entire device */ - il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); udelay(10); @@ -4224,7 +4169,18 @@ il_apm_stop(struct il_priv *il) * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); +} +EXPORT_SYMBOL(_il_apm_stop); + +void +il_apm_stop(struct il_priv *il) +{ + unsigned long flags; + + spin_lock_irqsave(&il->reg_lock, flags); + _il_apm_stop(il); + spin_unlock_irqrestore(&il->reg_lock, flags); } EXPORT_SYMBOL(il_apm_stop); @@ -4276,7 +4232,7 @@ il_apm_init(struct il_priv *il) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - if (il->cfg->base_params->set_l0s) { + if (il->cfg->set_l0s) { lctl = il_pcie_link_ctl(il); if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { @@ -4293,9 +4249,9 @@ il_apm_init(struct il_priv *il) } /* Configure analog phase-lock-loop before activating to D0A */ - if (il->cfg->base_params->pll_cfg_val) + if (il->cfg->pll_cfg_val) il_set_bit(il, CSR_ANA_PLL_CFG, - il->cfg->base_params->pll_cfg_val); + il->cfg->pll_cfg_val); /* * Set "initialization complete" bit to move adapter from @@ -4325,7 +4281,7 @@ il_apm_init(struct il_priv *il) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - if (il->cfg->base_params->use_bsm) + if (il->cfg->use_bsm) il_wr_prph(il, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); else @@ -4347,14 +4303,13 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) int ret; s8 prev_tx_power; bool defer; - struct il_rxon_context *ctx = &il->ctx; lockdep_assert_held(&il->mutex); if (il->tx_power_user_lmt == tx_power && !force) return 0; - if (!il->cfg->ops->lib->send_tx_power) + if (!il->ops->send_tx_power) return -EOPNOTSUPP; /* 0 dBm mean 1 milliwatt */ @@ -4378,7 +4333,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) /* do not set tx power when scanning or channel changing */ defer = test_bit(S_SCANNING, &il->status) || - memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); + memcmp(&il->active, &il->staging, sizeof(il->staging)); if (defer && !force) { D_INFO("Deferring tx power set\n"); return 0; @@ -4387,7 +4342,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force) prev_tx_power = il->tx_power_user_lmt; il->tx_power_user_lmt = tx_power; - ret = il->cfg->ops->lib->send_tx_power(il); + ret = il->ops->send_tx_power(il); /* if fail to set tx_power, restore the orig. tx power */ if (ret) { @@ -4505,15 +4460,15 @@ il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, spin_lock_irqsave(&il->lock, flags); - il->ctx.qos_data.def_qos_parm.ac[q].cw_min = + il->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); - il->ctx.qos_data.def_qos_parm.ac[q].cw_max = + il->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); - il->ctx.qos_data.def_qos_parm.ac[q].aifsn = params->aifs; - il->ctx.qos_data.def_qos_parm.ac[q].edca_txop = + il->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; + il->qos_data.def_qos_parm.ac[q].edca_txop = cpu_to_le16((params->txop * 32)); - il->ctx.qos_data.def_qos_parm.ac[q].reserved1 = 0; + il->qos_data.def_qos_parm.ac[q].reserved1 = 0; spin_unlock_irqrestore(&il->lock, flags); @@ -4526,60 +4481,36 @@ int il_mac_tx_last_beacon(struct ieee80211_hw *hw) { struct il_priv *il = hw->priv; + int ret; - return il->ibss_manager == IL_IBSS_MANAGER; -} -EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon); - -static int -il_set_mode(struct il_priv *il, struct il_rxon_context *ctx) -{ - il_connection_init_rx_config(il, ctx); + D_MAC80211("enter\n"); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + ret = (il->ibss_manager == IL_IBSS_MANAGER); - return il_commit_rxon(il, ctx); + D_MAC80211("leave ret %d\n", ret); + return ret; } +EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon); static int -il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx) +il_set_mode(struct il_priv *il) { - struct ieee80211_vif *vif = ctx->vif; - int err; + il_connection_init_rx_config(il); - lockdep_assert_held(&il->mutex); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); - /* - * This variable will be correct only when there's just - * a single context, but all code using it is for hardware - * that supports only one context. - */ - il->iw_mode = vif->type; - - ctx->is_active = true; - - err = il_set_mode(il, ctx); - if (err) { - if (!ctx->always_active) - ctx->is_active = false; - return err; - } - - return 0; + return il_commit_rxon(il); } int il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; int err; - u32 modes; - - D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); mutex_lock(&il->mutex); + D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); if (!il_is_ready_rf(il)) { IL_WARN("Try to add interface when device not ready\n"); @@ -4587,32 +4518,24 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) goto out; } - /* check if busy context is exclusive */ - if (il->ctx.vif && - (il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type))) { - err = -EINVAL; - goto out; - } - - modes = il->ctx.interface_modes | il->ctx.exclusive_interface_modes; - if (!(modes & BIT(vif->type))) { + if (il->vif) { err = -EOPNOTSUPP; goto out; } - vif_priv->ctx = &il->ctx; - il->ctx.vif = vif; + il->vif = vif; + il->iw_mode = vif->type; - err = il_setup_interface(il, &il->ctx); + err = il_set_mode(il); if (err) { - il->ctx.vif = NULL; + il->vif = NULL; il->iw_mode = NL80211_IFTYPE_STATION; } out: + D_MAC80211("leave err %d\n", err); mutex_unlock(&il->mutex); - D_MAC80211("leave\n"); return err; } EXPORT_SYMBOL(il_mac_add_interface); @@ -4621,8 +4544,6 @@ static void il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, bool mode_change) { - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - lockdep_assert_held(&il->mutex); if (il->scan_vif == vif) { @@ -4630,33 +4551,27 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, il_force_scan_end(il); } - if (!mode_change) { - il_set_mode(il, ctx); - if (!ctx->always_active) - ctx->is_active = false; - } + if (!mode_change) + il_set_mode(il); + } void il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - - D_MAC80211("enter\n"); mutex_lock(&il->mutex); + D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); - WARN_ON(ctx->vif != vif); - ctx->vif = NULL; + WARN_ON(il->vif != vif); + il->vif = NULL; il_teardown_interface(il, vif, false); - memset(il->bssid, 0, ETH_ALEN); - mutex_unlock(&il->mutex); D_MAC80211("leave\n"); - + mutex_unlock(&il->mutex); } EXPORT_SYMBOL(il_mac_remove_interface); @@ -4666,7 +4581,7 @@ il_alloc_txq_mem(struct il_priv *il) if (!il->txq) il->txq = kzalloc(sizeof(struct il_tx_queue) * - il->cfg->base_params->num_of_queues, GFP_KERNEL); + il->cfg->num_of_queues, GFP_KERNEL); if (!il->txq) { IL_ERR("Not enough memory for txq\n"); return -ENOMEM; @@ -4676,259 +4591,12 @@ il_alloc_txq_mem(struct il_priv *il) EXPORT_SYMBOL(il_alloc_txq_mem); void -il_txq_mem(struct il_priv *il) +il_free_txq_mem(struct il_priv *il) { kfree(il->txq); il->txq = NULL; } -EXPORT_SYMBOL(il_txq_mem); - -#ifdef CONFIG_IWLEGACY_DEBUGFS - -#define IL_TRAFFIC_DUMP_SIZE (IL_TRAFFIC_ENTRY_SIZE * IL_TRAFFIC_ENTRIES) - -void -il_reset_traffic_log(struct il_priv *il) -{ - il->tx_traffic_idx = 0; - il->rx_traffic_idx = 0; - if (il->tx_traffic) - memset(il->tx_traffic, 0, IL_TRAFFIC_DUMP_SIZE); - if (il->rx_traffic) - memset(il->rx_traffic, 0, IL_TRAFFIC_DUMP_SIZE); -} - -int -il_alloc_traffic_mem(struct il_priv *il) -{ - u32 traffic_size = IL_TRAFFIC_DUMP_SIZE; - - if (il_debug_level & IL_DL_TX) { - if (!il->tx_traffic) { - il->tx_traffic = kzalloc(traffic_size, GFP_KERNEL); - if (!il->tx_traffic) - return -ENOMEM; - } - } - if (il_debug_level & IL_DL_RX) { - if (!il->rx_traffic) { - il->rx_traffic = kzalloc(traffic_size, GFP_KERNEL); - if (!il->rx_traffic) - return -ENOMEM; - } - } - il_reset_traffic_log(il); - return 0; -} -EXPORT_SYMBOL(il_alloc_traffic_mem); - -void -il_free_traffic_mem(struct il_priv *il) -{ - kfree(il->tx_traffic); - il->tx_traffic = NULL; - - kfree(il->rx_traffic); - il->rx_traffic = NULL; -} -EXPORT_SYMBOL(il_free_traffic_mem); - -void -il_dbg_log_tx_data_frame(struct il_priv *il, u16 length, - struct ieee80211_hdr *header) -{ - __le16 fc; - u16 len; - - if (likely(!(il_debug_level & IL_DL_TX))) - return; - - if (!il->tx_traffic) - return; - - fc = header->frame_control; - if (ieee80211_is_data(fc)) { - len = - (length > - IL_TRAFFIC_ENTRY_SIZE) ? IL_TRAFFIC_ENTRY_SIZE : length; - memcpy((il->tx_traffic + - (il->tx_traffic_idx * IL_TRAFFIC_ENTRY_SIZE)), header, - len); - il->tx_traffic_idx = - (il->tx_traffic_idx + 1) % IL_TRAFFIC_ENTRIES; - } -} -EXPORT_SYMBOL(il_dbg_log_tx_data_frame); - -void -il_dbg_log_rx_data_frame(struct il_priv *il, u16 length, - struct ieee80211_hdr *header) -{ - __le16 fc; - u16 len; - - if (likely(!(il_debug_level & IL_DL_RX))) - return; - - if (!il->rx_traffic) - return; - - fc = header->frame_control; - if (ieee80211_is_data(fc)) { - len = - (length > - IL_TRAFFIC_ENTRY_SIZE) ? IL_TRAFFIC_ENTRY_SIZE : length; - memcpy((il->rx_traffic + - (il->rx_traffic_idx * IL_TRAFFIC_ENTRY_SIZE)), header, - len); - il->rx_traffic_idx = - (il->rx_traffic_idx + 1) % IL_TRAFFIC_ENTRIES; - } -} -EXPORT_SYMBOL(il_dbg_log_rx_data_frame); - -const char * -il_get_mgmt_string(int cmd) -{ - switch (cmd) { - IL_CMD(MANAGEMENT_ASSOC_REQ); - IL_CMD(MANAGEMENT_ASSOC_RESP); - IL_CMD(MANAGEMENT_REASSOC_REQ); - IL_CMD(MANAGEMENT_REASSOC_RESP); - IL_CMD(MANAGEMENT_PROBE_REQ); - IL_CMD(MANAGEMENT_PROBE_RESP); - IL_CMD(MANAGEMENT_BEACON); - IL_CMD(MANAGEMENT_ATIM); - IL_CMD(MANAGEMENT_DISASSOC); - IL_CMD(MANAGEMENT_AUTH); - IL_CMD(MANAGEMENT_DEAUTH); - IL_CMD(MANAGEMENT_ACTION); - default: - return "UNKNOWN"; - - } -} - -const char * -il_get_ctrl_string(int cmd) -{ - switch (cmd) { - IL_CMD(CONTROL_BACK_REQ); - IL_CMD(CONTROL_BACK); - IL_CMD(CONTROL_PSPOLL); - IL_CMD(CONTROL_RTS); - IL_CMD(CONTROL_CTS); - IL_CMD(CONTROL_ACK); - IL_CMD(CONTROL_CFEND); - IL_CMD(CONTROL_CFENDACK); - default: - return "UNKNOWN"; - - } -} - -void -il_clear_traffic_stats(struct il_priv *il) -{ - memset(&il->tx_stats, 0, sizeof(struct traffic_stats)); - memset(&il->rx_stats, 0, sizeof(struct traffic_stats)); -} - -/* - * if CONFIG_IWLEGACY_DEBUGFS defined, - * il_update_stats function will - * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass - * Use debugFs to display the rx/rx_stats - * if CONFIG_IWLEGACY_DEBUGFS not being defined, then no MGMT and CTRL - * information will be recorded, but DATA pkt still will be recorded - * for the reason of il_led.c need to control the led blinking based on - * number of tx and rx data. - * - */ -void -il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) -{ - struct traffic_stats *stats; - - if (is_tx) - stats = &il->tx_stats; - else - stats = &il->rx_stats; - - if (ieee80211_is_mgmt(fc)) { - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): - stats->mgmt[MANAGEMENT_ASSOC_REQ]++; - break; - case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): - stats->mgmt[MANAGEMENT_ASSOC_RESP]++; - break; - case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): - stats->mgmt[MANAGEMENT_REASSOC_REQ]++; - break; - case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): - stats->mgmt[MANAGEMENT_REASSOC_RESP]++; - break; - case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): - stats->mgmt[MANAGEMENT_PROBE_REQ]++; - break; - case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): - stats->mgmt[MANAGEMENT_PROBE_RESP]++; - break; - case cpu_to_le16(IEEE80211_STYPE_BEACON): - stats->mgmt[MANAGEMENT_BEACON]++; - break; - case cpu_to_le16(IEEE80211_STYPE_ATIM): - stats->mgmt[MANAGEMENT_ATIM]++; - break; - case cpu_to_le16(IEEE80211_STYPE_DISASSOC): - stats->mgmt[MANAGEMENT_DISASSOC]++; - break; - case cpu_to_le16(IEEE80211_STYPE_AUTH): - stats->mgmt[MANAGEMENT_AUTH]++; - break; - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): - stats->mgmt[MANAGEMENT_DEAUTH]++; - break; - case cpu_to_le16(IEEE80211_STYPE_ACTION): - stats->mgmt[MANAGEMENT_ACTION]++; - break; - } - } else if (ieee80211_is_ctl(fc)) { - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_BACK_REQ): - stats->ctrl[CONTROL_BACK_REQ]++; - break; - case cpu_to_le16(IEEE80211_STYPE_BACK): - stats->ctrl[CONTROL_BACK]++; - break; - case cpu_to_le16(IEEE80211_STYPE_PSPOLL): - stats->ctrl[CONTROL_PSPOLL]++; - break; - case cpu_to_le16(IEEE80211_STYPE_RTS): - stats->ctrl[CONTROL_RTS]++; - break; - case cpu_to_le16(IEEE80211_STYPE_CTS): - stats->ctrl[CONTROL_CTS]++; - break; - case cpu_to_le16(IEEE80211_STYPE_ACK): - stats->ctrl[CONTROL_ACK]++; - break; - case cpu_to_le16(IEEE80211_STYPE_CFEND): - stats->ctrl[CONTROL_CFEND]++; - break; - case cpu_to_le16(IEEE80211_STYPE_CFENDACK): - stats->ctrl[CONTROL_CFENDACK]++; - break; - } - } else { - /* data */ - stats->data_cnt++; - stats->data_bytes += len; - } -} -EXPORT_SYMBOL(il_update_stats); -#endif +EXPORT_SYMBOL(il_free_txq_mem); int il_force_reset(struct il_priv *il, bool external) @@ -4987,15 +4655,18 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p) { struct il_priv *il = hw->priv; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - u32 modes; int err; - newtype = ieee80211_iftype_p2p(newtype, newp2p); - mutex_lock(&il->mutex); + D_MAC80211("enter: type %d, addr %pM newtype %d newp2p %d\n", + vif->type, vif->addr, newtype, newp2p); - if (!ctx->vif || !il_is_ready_rf(il)) { + if (newp2p) { + err = -EOPNOTSUPP; + goto out; + } + + if (!il->vif || !il_is_ready_rf(il)) { /* * Huh? But wait ... this can maybe happen when * we're in the middle of a firmware restart! @@ -5004,23 +4675,11 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } - modes = ctx->interface_modes | ctx->exclusive_interface_modes; - if (!(modes & BIT(newtype))) { - err = -EOPNOTSUPP; - goto out; - } - - if ((il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type)) || - (il->ctx.exclusive_interface_modes & BIT(newtype))) { - err = -EINVAL; - goto out; - } - /* success */ il_teardown_interface(il, vif, true); vif->type = newtype; - vif->p2p = newp2p; - err = il_setup_interface(il, ctx); + vif->p2p = false; + err = il_set_mode(il); WARN_ON(err); /* * We've switched internally, but submitting to the @@ -5032,7 +4691,9 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, err = 0; out: + D_MAC80211("leave err %d\n", err); mutex_unlock(&il->mutex); + return err; } EXPORT_SYMBOL(il_mac_change_interface); @@ -5056,11 +4717,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt) timeout = txq->time_stamp + - msecs_to_jiffies(il->cfg->base_params->wd_timeout); + msecs_to_jiffies(il->cfg->wd_timeout); if (time_after(jiffies, timeout)) { IL_ERR("Queue %d stuck for %u ms.\n", q->id, - il->cfg->base_params->wd_timeout); + il->cfg->wd_timeout); ret = il_force_reset(il, false); return (ret == -EAGAIN) ? 0 : 1; } @@ -5088,7 +4749,7 @@ il_bg_watchdog(unsigned long data) if (test_bit(S_EXIT_PENDING, &il->status)) return; - timeout = il->cfg->base_params->wd_timeout; + timeout = il->cfg->wd_timeout; if (timeout == 0) return; @@ -5115,7 +4776,7 @@ EXPORT_SYMBOL(il_bg_watchdog); void il_setup_watchdog(struct il_priv *il) { - unsigned int timeout = il->cfg->base_params->wd_timeout; + unsigned int timeout = il->cfg->wd_timeout; if (timeout) mod_timer(&il->watchdog, @@ -5229,9 +4890,9 @@ il_pci_resume(struct device *device) hw_rfkill = true; if (hw_rfkill) - set_bit(S_RF_KILL_HW, &il->status); + set_bit(S_RFKILL, &il->status); else - clear_bit(S_RF_KILL_HW, &il->status); + clear_bit(S_RFKILL, &il->status); wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rfkill); @@ -5252,28 +4913,25 @@ EXPORT_SYMBOL(il_pm_ops); #endif /* CONFIG_PM */ static void -il_update_qos(struct il_priv *il, struct il_rxon_context *ctx) +il_update_qos(struct il_priv *il) { if (test_bit(S_EXIT_PENDING, &il->status)) return; - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; + il->qos_data.def_qos_parm.qos_flags = 0; - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= + if (il->qos_data.qos_active) + il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + if (il->ht.enabled) + il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); + il->qos_data.qos_active, il->qos_data.def_qos_parm.qos_flags); - il_send_cmd_pdu_async(il, ctx->qos_cmd, sizeof(struct il_qosparam_cmd), - &ctx->qos_data.def_qos_parm, NULL); + il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd), + &il->qos_data.def_qos_parm, NULL); } /** @@ -5287,19 +4945,14 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = conf->channel; struct il_ht_config *ht_conf = &il->current_ht_config; - struct il_rxon_context *ctx = &il->ctx; unsigned long flags = 0; int ret = 0; u16 ch; int scan_active = 0; bool ht_changed = false; - if (WARN_ON(!il->cfg->ops->legacy)) - return -EOPNOTSUPP; - mutex_lock(&il->mutex); - - D_MAC80211("enter to channel %d changed 0x%X\n", channel->hw_value, + D_MAC80211("enter: channel %d changed 0x%X\n", channel->hw_value, changed); if (unlikely(test_bit(S_SCANNING, &il->status))) { @@ -5319,8 +4972,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) * set up the SM PS mode to OFF if an HT channel is * configured. */ - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); } /* during scanning mac80211 will delay channel setting until @@ -5349,48 +5002,48 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) spin_lock_irqsave(&il->lock, flags); /* Configure HT40 channels */ - if (ctx->ht.enabled != conf_is_ht(conf)) { - ctx->ht.enabled = conf_is_ht(conf); + if (il->ht.enabled != conf_is_ht(conf)) { + il->ht.enabled = conf_is_ht(conf); ht_changed = true; } - if (ctx->ht.enabled) { + if (il->ht.enabled) { if (conf_is_ht40_minus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else if (conf_is_ht40_plus(conf)) { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ctx->ht.is_40mhz = true; + il->ht.is_40mhz = true; } else { - ctx->ht.extension_chan_offset = + il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; } } else - ctx->ht.is_40mhz = false; + il->ht.is_40mhz = false; /* * Default to no protection. Protection mode will * later be set from BSS config in il_ht_conf */ - ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + il->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; /* if we are switching from ht to 2.4 clear flags * from any ht related info since 2.4 does not * support ht */ - if ((le16_to_cpu(ctx->staging.channel) != ch)) - ctx->staging.flags = 0; + if ((le16_to_cpu(il->staging.channel) != ch)) + il->staging.flags = 0; - il_set_rxon_channel(il, channel, ctx); + il_set_rxon_channel(il, channel); il_set_rxon_ht(il, ht_conf); - il_set_flags_for_band(il, ctx, channel->band, ctx->vif); + il_set_flags_for_band(il, channel->band, il->vif); spin_unlock_irqrestore(&il->lock, flags); - if (il->cfg->ops->legacy->update_bcast_stations) - ret = il->cfg->ops->legacy->update_bcast_stations(il); + if (il->ops->update_bcast_stations) + ret = il->ops->update_bcast_stations(il); set_ch_out: /* The list of supported rates and rate mask can be different @@ -5420,16 +5073,17 @@ set_ch_out: if (scan_active) goto out; - if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) - il_commit_rxon(il, ctx); + if (memcmp(&il->active, &il->staging, sizeof(il->staging))) + il_commit_rxon(il); else D_INFO("Not re-sending same RXON configuration.\n"); if (ht_changed) - il_update_qos(il, ctx); + il_update_qos(il); out: - D_MAC80211("leave\n"); + D_MAC80211("leave ret %d\n", ret); mutex_unlock(&il->mutex); + return ret; } EXPORT_SYMBOL(il_mac_config); @@ -5439,26 +5093,18 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct il_priv *il = hw->priv; unsigned long flags; - struct il_rxon_context *ctx = &il->ctx; - - if (WARN_ON(!il->cfg->ops->legacy)) - return; mutex_lock(&il->mutex); - D_MAC80211("enter\n"); + D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr); spin_lock_irqsave(&il->lock, flags); - memset(&il->current_ht_config, 0, sizeof(struct il_ht_config)); - spin_unlock_irqrestore(&il->lock, flags); - spin_lock_irqsave(&il->lock, flags); + memset(&il->current_ht_config, 0, sizeof(struct il_ht_config)); /* new association get rid of ibss beacon skb */ if (il->beacon_skb) dev_kfree_skb(il->beacon_skb); - il->beacon_skb = NULL; - il->timestamp = 0; spin_unlock_irqrestore(&il->lock, flags); @@ -5470,17 +5116,14 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return; } - /* we are restarting association process - * clear RXON_FILTER_ASSOC_MSK bit - */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - il_commit_rxon(il, ctx); + /* we are restarting association process */ + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il_commit_rxon(il); il_set_rate(il); - mutex_unlock(&il->mutex); - D_MAC80211("leave\n"); + mutex_unlock(&il->mutex); } EXPORT_SYMBOL(il_mac_reset_tsf); @@ -5490,16 +5133,15 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif) struct il_ht_config *ht_conf = &il->current_ht_config; struct ieee80211_sta *sta; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); D_ASSOC("enter:\n"); - if (!ctx->ht.enabled) + if (!il->ht.enabled) return; - ctx->ht.protection = + il->ht.protection = bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ctx->ht.non_gf_sta_present = + il->ht.non_gf_sta_present = !!(bss_conf-> ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); @@ -5548,16 +5190,14 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif) static inline void il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif) { - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - /* * inform the ucode that there is no longer an * association and that no more packets should be * sent */ - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ctx->staging.assoc_id = 0; - il_commit_rxon(il, ctx); + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + il->staging.assoc_id = 0; + il_commit_rxon(il); } static void @@ -5575,8 +5215,8 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) lockdep_assert_held(&il->mutex); - if (!il->beacon_ctx) { - IL_ERR("update beacon but no beacon context!\n"); + if (!il->beacon_enabled) { + IL_ERR("update beacon with no beaconing enabled\n"); dev_kfree_skb(skb); return; } @@ -5599,7 +5239,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return; } - il->cfg->ops->legacy->post_associate(il); + il->ops->post_associate(il); } void @@ -5607,17 +5247,13 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes) { struct il_priv *il = hw->priv; - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); int ret; - if (WARN_ON(!il->cfg->ops->legacy)) - return; - - D_MAC80211("changes = 0x%X\n", changes); - mutex_lock(&il->mutex); + D_MAC80211("enter: changes 0x%x\n", changes); if (!il_is_alive(il)) { + D_MAC80211("leave - not alive\n"); mutex_unlock(&il->mutex); return; } @@ -5626,21 +5262,17 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned long flags; spin_lock_irqsave(&il->lock, flags); - ctx->qos_data.qos_active = bss_conf->qos; - il_update_qos(il, ctx); + il->qos_data.qos_active = bss_conf->qos; + il_update_qos(il); spin_unlock_irqrestore(&il->lock, flags); } if (changes & BSS_CHANGED_BEACON_ENABLED) { - /* - * the add_interface code must make sure we only ever - * have a single interface that could be beaconing at - * any time. - */ + /* FIXME: can we remove beacon_enabled ? */ if (vif->bss_conf.enable_beacon) - il->beacon_ctx = ctx; + il->beacon_enabled = true; else - il->beacon_ctx = NULL; + il->beacon_enabled = false; } if (changes & BSS_CHANGED_BSSID) { @@ -5652,23 +5284,20 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, * below/in post_associate will fail. */ if (il_scan_cancel_timeout(il, 100)) { - IL_WARN("Aborted scan still in progress after 100ms\n"); - D_MAC80211("leaving - scan abort failed.\n"); + D_MAC80211("leave - scan abort failed\n"); mutex_unlock(&il->mutex); return; } /* mac80211 only sets assoc when in STATION mode */ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(ctx->staging.bssid_addr, bss_conf->bssid, + memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); /* currently needed in a few places */ memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); - } else { - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - } - + } else + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } /* @@ -5682,21 +5311,21 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_ERP_PREAMBLE) { D_MAC80211("ERP_PREAMBLE %d\n", bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) - ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; } if (changes & BSS_CHANGED_ERP_CTS_PROT) { D_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && il->band != IEEE80211_BAND_5GHZ) - ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; + il->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; else - ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + il->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; if (bss_conf->use_cts_prot) - ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; + il->staging.flags |= RXON_FLG_SELF_CTS_EN; else - ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; + il->staging.flags &= ~RXON_FLG_SELF_CTS_EN; } if (changes & BSS_CHANGED_BASIC_RATES) { @@ -5706,12 +5335,12 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, * like this here: * if (A-band) - ctx->staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = bss_conf->basic_rates; else - ctx->staging.ofdm_basic_rates = + il->staging.ofdm_basic_rates = bss_conf->basic_rates >> 4; - ctx->staging.cck_basic_rates = + il->staging.cck_basic_rates = bss_conf->basic_rates & 0xF; */ } @@ -5719,55 +5348,52 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (changes & BSS_CHANGED_HT) { il_ht_conf(il, vif); - if (il->cfg->ops->hcmd->set_rxon_chain) - il->cfg->ops->hcmd->set_rxon_chain(il, ctx); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); } if (changes & BSS_CHANGED_ASSOC) { D_MAC80211("ASSOC %d\n", bss_conf->assoc); if (bss_conf->assoc) { - il->timestamp = bss_conf->timestamp; + il->timestamp = bss_conf->last_tsf; if (!il_is_rfkill(il)) - il->cfg->ops->legacy->post_associate(il); + il->ops->post_associate(il); } else il_set_no_assoc(il, vif); } - if (changes && il_is_associated_ctx(ctx) && bss_conf->aid) { + if (changes && il_is_associated(il) && bss_conf->aid) { D_MAC80211("Changes (%#x) while associated\n", changes); - ret = il_send_rxon_assoc(il, ctx); + ret = il_send_rxon_assoc(il); if (!ret) { /* Sync active_rxon with latest change. */ - memcpy((void *)&ctx->active, &ctx->staging, + memcpy((void *)&il->active, &il->staging, sizeof(struct il_rxon_cmd)); } } if (changes & BSS_CHANGED_BEACON_ENABLED) { if (vif->bss_conf.enable_beacon) { - memcpy(ctx->staging.bssid_addr, bss_conf->bssid, + memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(il->bssid, bss_conf->bssid, ETH_ALEN); - il->cfg->ops->legacy->config_ap(il); + il->ops->config_ap(il); } else il_set_no_assoc(il, vif); } if (changes & BSS_CHANGED_IBSS) { - ret = - il->cfg->ops->legacy->manage_ibss_station(il, vif, - bss_conf-> - ibss_joined); + ret = il->ops->manage_ibss_station(il, vif, + bss_conf->ibss_joined); if (ret) IL_ERR("failed to %s IBSS station %pM\n", bss_conf->ibss_joined ? "add" : "remove", bss_conf->bssid); } - mutex_unlock(&il->mutex); - D_MAC80211("leave\n"); + mutex_unlock(&il->mutex); } EXPORT_SYMBOL(il_mac_bss_info_changed); diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index abfa388588b..5f5017767b9 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -143,12 +143,6 @@ struct il_queue { * space less than this */ }; -/* One for each TFD */ -struct il_tx_info { - struct sk_buff *skb; - struct il_rxon_context *ctx; -}; - /** * struct il_tx_queue - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor @@ -156,7 +150,7 @@ struct il_tx_info { * @cmd: array of command/TX buffer pointers * @meta: array of meta data for each command/tx buffer * @dma_addr_cmd: physical address of cmd/tx buffer array - * @txb: array of per-TFD driver data + * @skbs: array of per-TFD socket buffer pointers * @time_stamp: time (in jiffies) of last read_ptr change * @need_update: indicates need to update read/write idx * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled @@ -172,7 +166,7 @@ struct il_tx_queue { void *tfds; struct il_device_cmd **cmd; struct il_cmd_meta *meta; - struct il_tx_info *txb; + struct sk_buff **skbs; unsigned long time_stamp; u8 need_update; u8 sched_retry; @@ -431,12 +425,6 @@ struct il_eeprom_calib_info { #define EEPROM_REGULATORY_BAND_NO_HT40 (0) -struct il_eeprom_ops { - const u32 regulatory_bands[7]; - int (*acquire_semaphore) (struct il_priv *il); - void (*release_semaphore) (struct il_priv *il); -}; - int il_eeprom_init(struct il_priv *il); void il_eeprom_free(struct il_priv *il); const u8 *il_eeprom_query_addr(const struct il_priv *il, size_t offset); @@ -735,13 +723,12 @@ struct il_qos_info { struct il_station_entry { struct il_addsta_cmd sta; struct il_tid_data tid[MAX_TID_COUNT]; - u8 used, ctxid; + u8 used; struct il_hw_key keyinfo; struct il_link_quality_cmd *lq; }; struct il_station_priv_common { - struct il_rxon_context *ctx; u8 sta_id; }; @@ -752,7 +739,6 @@ struct il_station_priv_common { * space for us to put data into. */ struct il_vif_priv { - struct il_rxon_context *ctx; u8 ibss_bssid_sta_id; }; @@ -816,6 +802,7 @@ struct il_sensitivity_ranges { /** * struct il_hw_params + * @bcast_id: f/w broadcast station ID * @max_txq_num: Max # Tx queues supported * @dma_chnl_num: Number of Tx DMA/FIFO channels * @scd_bc_tbls_size: size of scheduler byte count tables @@ -836,6 +823,7 @@ struct il_sensitivity_ranges { * @struct il_sensitivity_ranges: range of sensitivity values */ struct il_hw_params { + u8 bcast_id; u8 max_txq_num; u8 dma_chnl_num; u16 scd_bc_tbls_size; @@ -968,26 +956,6 @@ enum il4965_chain_noise_state { IL_CHAIN_NOISE_DONE, }; -enum il4965_calib_enabled_state { - IL_CALIB_DISABLED = 0, /* must be 0 */ - IL_CALIB_ENABLED = 1, -}; - -/* - * enum il_calib - * defines the order in which results of initial calibrations - * should be sent to the runtime uCode - */ -enum il_calib { - IL_CALIB_MAX, -}; - -/* Opaque calibration results */ -struct il_calib_result { - void *buf; - size_t buf_len; -}; - enum ucode_type { UCODE_NONE = 0, UCODE_INIT, @@ -1152,55 +1120,6 @@ struct il_force_reset { struct il_rxon_context { struct ieee80211_vif *vif; - - const u8 *ac_to_fifo; - const u8 *ac_to_queue; - u8 mcast_queue; - - /* - * We could use the vif to indicate active, but we - * also need it to be active during disabling when - * we already removed the vif for type setting. - */ - bool always_active, is_active; - - bool ht_need_multiple_chains; - - int ctxid; - - u32 interface_modes, exclusive_interface_modes; - u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; - - /* - * We declare this const so it can only be - * changed via explicit cast within the - * routines that actually update the physical - * hardware. - */ - const struct il_rxon_cmd active; - struct il_rxon_cmd staging; - - struct il_rxon_time_cmd timing; - - struct il_qos_info qos_data; - - u8 bcast_sta_id, ap_sta_id; - - u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; - u8 qos_cmd; - u8 wep_key_cmd; - - struct il_wep_key wep_keys[WEP_KEYS_MAX]; - u8 key_mapping_keys; - - __le32 station_flags; - - struct { - bool non_gf_sta_present; - u8 protection; - bool enabled, is_40mhz; - u8 extension_chan_offset; - } ht; }; struct il_power_mgr { @@ -1211,12 +1130,15 @@ struct il_power_mgr { }; struct il_priv { - - /* ieee device used by generic ieee processing code */ struct ieee80211_hw *hw; struct ieee80211_channel *ieee_channels; struct ieee80211_rate *ieee_rates; + struct il_cfg *cfg; + const struct il_ops *ops; +#ifdef CONFIG_IWLEGACY_DEBUGFS + const struct il_debugfs_ops *debugfs_ops; +#endif /* temporary frame storage list */ struct list_head free_frames; @@ -1253,9 +1175,6 @@ struct il_priv { s32 temperature; /* degrees Kelvin */ s32 last_temperature; - /* init calibration results */ - struct il_calib_result calib_results[IL_CALIB_MAX]; - /* Scan related variables */ unsigned long scan_start; unsigned long scan_start_tsf; @@ -1304,7 +1223,28 @@ struct il_priv { u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; - struct il_rxon_context ctx; + struct ieee80211_vif *vif; + + struct il_qos_info qos_data; + + struct { + bool enabled; + bool is_40mhz; + bool non_gf_sta_present; + u8 protection; + u8 extension_chan_offset; + } ht; + + /* + * We declare this const so it can only be + * changed via explicit cast within the + * routines that actually update the physical + * hardware. + */ + const struct il_rxon_cmd active; + struct il_rxon_cmd staging; + + struct il_rxon_time_cmd timing; __le16 switch_channel; @@ -1427,6 +1367,9 @@ struct il_priv { u8 phy_calib_chain_noise_reset_cmd; u8 phy_calib_chain_noise_gain_cmd; + u8 key_mapping_keys; + struct il_wep_key wep_keys[WEP_KEYS_MAX]; + struct il_notif_stats stats; #ifdef CONFIG_IWLEGACY_DEBUGFS struct il_notif_stats accum_stats; @@ -1449,7 +1392,7 @@ struct il_priv { struct work_struct rx_replenish; struct work_struct abort_scan; - struct il_rxon_context *beacon_ctx; + bool beacon_enabled; struct sk_buff *beacon_skb; struct work_struct tx_flush; @@ -1507,30 +1450,10 @@ il_txq_ctx_deactivate(struct il_priv *il, int txq_id) clear_bit(txq_id, &il->txq_ctx_active_msk); } -static inline struct ieee80211_hdr * -il_tx_queue_get_hdr(struct il_priv *il, int txq_id, int idx) -{ - if (il->txq[txq_id].txb[idx].skb) - return (struct ieee80211_hdr *)il->txq[txq_id].txb[idx].skb-> - data; - return NULL; -} - -static inline struct il_rxon_context * -il_rxon_ctx_from_vif(struct ieee80211_vif *vif) -{ - struct il_vif_priv *vif_priv = (void *)vif->drv_priv; - - return vif_priv->ctx; -} - -#define for_each_context(il, _ctx) \ - for (_ctx = &il->ctx; _ctx == &il->ctx; _ctx++) - static inline int il_is_associated(struct il_priv *il) { - return (il->ctx.active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; + return (il->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; } static inline int @@ -1540,12 +1463,6 @@ il_is_any_associated(struct il_priv *il) } static inline int -il_is_associated_ctx(struct il_rxon_context *ctx) -{ - return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; -} - -static inline int il_is_channel_valid(const struct il_channel_info *ch_info) { if (ch_info == NULL) @@ -1613,25 +1530,6 @@ il_free_pages(struct il_priv *il, unsigned long page) #define IL_RX_BUF_SIZE_4K (4 * 1024) #define IL_RX_BUF_SIZE_8K (8 * 1024) -struct il_hcmd_ops { - int (*rxon_assoc) (struct il_priv *il, struct il_rxon_context *ctx); - int (*commit_rxon) (struct il_priv *il, struct il_rxon_context *ctx); - void (*set_rxon_chain) (struct il_priv *il, - struct il_rxon_context *ctx); -}; - -struct il_hcmd_utils_ops { - u16(*get_hcmd_size) (u8 cmd_id, u16 len); - u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data); - int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif); - void (*post_scan) (struct il_priv *il); -}; - -struct il_apm_ops { - int (*init) (struct il_priv *il); - void (*config) (struct il_priv *il); -}; - #ifdef CONFIG_IWLEGACY_DEBUGFS struct il_debugfs_ops { ssize_t(*rx_stats_read) (struct file *file, char __user *user_buf, @@ -1644,13 +1542,7 @@ struct il_debugfs_ops { }; #endif -struct il_temp_ops { - void (*temperature) (struct il_priv *il); -}; - -struct il_lib_ops { - /* set hw dependent parameters */ - int (*set_hw_params) (struct il_priv *il); +struct il_ops { /* Handling TX */ void (*txq_update_byte_cnt_tbl) (struct il_priv *il, struct il_tx_queue *txq, @@ -1660,8 +1552,6 @@ struct il_lib_ops { u16 len, u8 reset, u8 pad); void (*txq_free_tfd) (struct il_priv *il, struct il_tx_queue *txq); int (*txq_init) (struct il_priv *il, struct il_tx_queue *txq); - /* setup Rx handler */ - void (*handler_setup) (struct il_priv *il); /* alive notification after init uCode load */ void (*init_alive_start) (struct il_priv *il); /* check validity of rtc data address */ @@ -1674,45 +1564,33 @@ struct il_lib_ops { int (*set_channel_switch) (struct il_priv *il, struct ieee80211_channel_switch *ch_switch); /* power management */ - struct il_apm_ops apm_ops; + int (*apm_init) (struct il_priv *il); - /* power */ + /* tx power */ int (*send_tx_power) (struct il_priv *il); void (*update_chain_flags) (struct il_priv *il); /* eeprom operations */ - struct il_eeprom_ops eeprom_ops; + int (*eeprom_acquire_semaphore) (struct il_priv *il); + void (*eeprom_release_semaphore) (struct il_priv *il); - /* temperature */ - struct il_temp_ops temp_ops; - -#ifdef CONFIG_IWLEGACY_DEBUGFS - struct il_debugfs_ops debugfs_ops; -#endif + int (*rxon_assoc) (struct il_priv *il); + int (*commit_rxon) (struct il_priv *il); + void (*set_rxon_chain) (struct il_priv *il); -}; - -struct il_led_ops { - int (*cmd) (struct il_priv *il, struct il_led_cmd *led_cmd); -}; + u16(*get_hcmd_size) (u8 cmd_id, u16 len); + u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data); -struct il_legacy_ops { + int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif); + void (*post_scan) (struct il_priv *il); void (*post_associate) (struct il_priv *il); void (*config_ap) (struct il_priv *il); /* station management */ int (*update_bcast_stations) (struct il_priv *il); int (*manage_ibss_station) (struct il_priv *il, struct ieee80211_vif *vif, bool add); -}; -struct il_ops { - const struct il_lib_ops *lib; - const struct il_hcmd_ops *hcmd; - const struct il_hcmd_utils_ops *utils; - const struct il_led_ops *led; - const struct il_nic_ops *nic; - const struct il_legacy_ops *legacy; - const struct ieee80211_ops *ieee80211_ops; + int (*send_led_cmd) (struct il_priv *il, struct il_led_cmd *led_cmd); }; struct il_mod_params { @@ -1725,37 +1603,6 @@ struct il_mod_params { int restart_fw; /* def: 1 = restart firmware */ }; -/* - * @led_compensation: compensate on the led on/off time per HW according - * to the deviation to achieve the desired led frequency. - * The detail algorithm is described in common.c - * @chain_noise_num_beacons: number of beacons used to compute chain noise - * @wd_timeout: TX queues watchdog timeout - * @temperature_kelvin: temperature report by uCode in kelvin - * @ucode_tracing: support ucode continuous tracing - * @sensitivity_calib_by_driver: driver has the capability to perform - * sensitivity calibration operation - * @chain_noise_calib_by_driver: driver has the capability to perform - * chain noise calibration operation - */ -struct il_base_params { - int eeprom_size; - int num_of_queues; /* def: HW dependent */ - int num_of_ampdu_queues; /* def: HW dependent */ - /* for il_apm_init() */ - u32 pll_cfg_val; - bool set_l0s; - bool use_bsm; - - u16 led_compensation; - int chain_noise_num_beacons; - unsigned int wd_timeout; - bool temperature_kelvin; - const bool ucode_tracing; - const bool sensitivity_calib_by_driver; - const bool chain_noise_calib_by_driver; -}; - #define IL_LED_SOLID 11 #define IL_DEF_LED_INTRVL cpu_to_le32(1000) @@ -1821,7 +1668,6 @@ struct il_cfg { unsigned int sku; u16 eeprom_ver; u16 eeprom_calib_ver; - const struct il_ops *ops; /* module based parameters which can be set from modprobe cmd */ const struct il_mod_params *mod_params; /* params not likely to change within a device family */ @@ -1829,31 +1675,45 @@ struct il_cfg { /* params likely to change within a device family */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; enum il_led_mode led_mode; + + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues; /* def: HW dependent */ + /* for il_apm_init() */ + u32 pll_cfg_val; + bool set_l0s; + bool use_bsm; + + u16 led_compensation; + int chain_noise_num_beacons; + unsigned int wd_timeout; + bool temperature_kelvin; + const bool ucode_tracing; + const bool sensitivity_calib_by_driver; + const bool chain_noise_calib_by_driver; + + const u32 regulatory_bands[7]; }; /*************************** * L i b * ***************************/ -struct ieee80211_hw *il_alloc_all(struct il_cfg *cfg); int il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params); int il_mac_tx_last_beacon(struct ieee80211_hw *hw); -void il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx, - int hw_decrypt); -int il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx); -int il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx); -int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch, - struct il_rxon_context *ctx); -void il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx, - enum ieee80211_band band, struct ieee80211_vif *vif); +void il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt); +int il_check_rxon_cmd(struct il_priv *il); +int il_full_rxon_required(struct il_priv *il); +int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch); +void il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band, + struct ieee80211_vif *vif); u8 il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band); void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf); -bool il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx, +bool il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap); -void il_connection_init_rx_config(struct il_priv *il, - struct il_rxon_context *ctx); +void il_connection_init_rx_config(struct il_priv *il); void il_set_rate(struct il_priv *il); int il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr, u32 decrypt_res, struct ieee80211_rx_status *stats); @@ -1864,60 +1724,24 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); int il_alloc_txq_mem(struct il_priv *il); -void il_txq_mem(struct il_priv *il); +void il_free_txq_mem(struct il_priv *il); #ifdef CONFIG_IWLEGACY_DEBUGFS -int il_alloc_traffic_mem(struct il_priv *il); -void il_free_traffic_mem(struct il_priv *il); -void il_reset_traffic_log(struct il_priv *il); -void il_dbg_log_tx_data_frame(struct il_priv *il, u16 length, - struct ieee80211_hdr *header); -void il_dbg_log_rx_data_frame(struct il_priv *il, u16 length, - struct ieee80211_hdr *header); -const char *il_get_mgmt_string(int cmd); -const char *il_get_ctrl_string(int cmd); -void il_clear_traffic_stats(struct il_priv *il); -void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len); +extern void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len); #else -static inline int -il_alloc_traffic_mem(struct il_priv *il) -{ - return 0; -} - -static inline void -il_free_traffic_mem(struct il_priv *il) -{ -} - -static inline void -il_reset_traffic_log(struct il_priv *il) -{ -} - -static inline void -il_dbg_log_tx_data_frame(struct il_priv *il, u16 length, - struct ieee80211_hdr *header) -{ -} - -static inline void -il_dbg_log_rx_data_frame(struct il_priv *il, u16 length, - struct ieee80211_hdr *header) -{ -} - static inline void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) { } #endif + /***************************************************** - * RX handlers. - * **************************************************/ + * Handlers + ***************************************************/ void il_hdl_pm_sleep(struct il_priv *il, struct il_rx_buf *rxb); void il_hdl_pm_debug_stats(struct il_priv *il, struct il_rx_buf *rxb); void il_hdl_error(struct il_priv *il, struct il_rx_buf *rxb); +void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb); /***************************************************** * RX @@ -1928,25 +1752,20 @@ int il_rx_queue_alloc(struct il_priv *il); void il_rx_queue_update_write_ptr(struct il_priv *il, struct il_rx_queue *q); int il_rx_queue_space(const struct il_rx_queue *q); void il_tx_cmd_complete(struct il_priv *il, struct il_rx_buf *rxb); -/* Handlers */ + void il_hdl_spectrum_measurement(struct il_priv *il, struct il_rx_buf *rxb); void il_recover_from_stats(struct il_priv *il, struct il_rx_pkt *pkt); void il_chswitch_done(struct il_priv *il, bool is_success); -void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb); - -/* TX helpers */ /***************************************************** * TX ******************************************************/ -void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); -int il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num, - u32 txq_id); -void il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, - int slots_num, u32 txq_id); -void il_tx_queue_unmap(struct il_priv *il, int txq_id); -void il_tx_queue_free(struct il_priv *il, int txq_id); -void il_setup_watchdog(struct il_priv *il); +extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); +extern int il_tx_queue_init(struct il_priv *il, u32 txq_id); +extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id); +extern void il_tx_queue_unmap(struct il_priv *il, int txq_id); +extern void il_tx_queue_free(struct il_priv *il, int txq_id); +extern void il_setup_watchdog(struct il_priv *il); /***************************************************** * TX power ****************************************************/ @@ -1956,7 +1775,7 @@ int il_set_tx_power(struct il_priv *il, s8 tx_power, bool force); * Rate ******************************************************************************/ -u8 il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx); +u8 il_get_lowest_plcp(struct il_priv *il); /******************************************************************************* * Scanning @@ -2043,10 +1862,10 @@ extern const struct dev_pm_ops il_pm_ops; ******************************************************/ void il4965_dump_nic_error_log(struct il_priv *il); #ifdef CONFIG_IWLEGACY_DEBUG -void il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx); +void il_print_rx_config_cmd(struct il_priv *il); #else static inline void -il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx) +il_print_rx_config_cmd(struct il_priv *il) { } #endif @@ -2064,7 +1883,7 @@ void il_free_geos(struct il_priv *il); #define S_HCMD_ACTIVE 0 /* host command in progress */ /* 1 is unused (used to be S_HCMD_SYNC_ACTIVE) */ #define S_INT_ENABLED 2 -#define S_RF_KILL_HW 3 +#define S_RFKILL 3 #define S_CT_KILL 4 #define S_INIT 5 #define S_ALIVE 6 @@ -2103,15 +1922,9 @@ il_is_init(struct il_priv *il) } static inline int -il_is_rfkill_hw(struct il_priv *il) -{ - return test_bit(S_RF_KILL_HW, &il->status); -} - -static inline int il_is_rfkill(struct il_priv *il) { - return il_is_rfkill_hw(il); + return test_bit(S_RFKILL, &il->status); } static inline int @@ -2132,20 +1945,23 @@ il_is_ready_rf(struct il_priv *il) extern void il_send_bt_config(struct il_priv *il); extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); -void il_apm_stop(struct il_priv *il); +extern void il_apm_stop(struct il_priv *il); +extern void _il_apm_stop(struct il_priv *il); + int il_apm_init(struct il_priv *il); -int il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx); +int il_send_rxon_timing(struct il_priv *il); + static inline int -il_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx) +il_send_rxon_assoc(struct il_priv *il) { - return il->cfg->ops->hcmd->rxon_assoc(il, ctx); + return il->ops->rxon_assoc(il); } static inline int -il_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx) +il_commit_rxon(struct il_priv *il) { - return il->cfg->ops->hcmd->commit_rxon(il, ctx); + return il->ops->commit_rxon(il); } static inline const struct ieee80211_supported_band * @@ -2166,7 +1982,7 @@ irqreturn_t il_isr(int irq, void *data); extern void il_set_bit(struct il_priv *p, u32 r, u32 m); extern void il_clear_bit(struct il_priv *p, u32 r, u32 m); -extern int _il_grab_nic_access(struct il_priv *il); +extern bool _il_grab_nic_access(struct il_priv *il); extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); extern u32 il_rd_prph(struct il_priv *il, u32 reg); @@ -2177,20 +1993,20 @@ extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); static inline void _il_write8(struct il_priv *il, u32 ofs, u8 val) { - iowrite8(val, il->hw_base + ofs); + writeb(val, il->hw_base + ofs); } #define il_write8(il, ofs, val) _il_write8(il, ofs, val) static inline void _il_wr(struct il_priv *il, u32 ofs, u32 val) { - iowrite32(val, il->hw_base + ofs); + writel(val, il->hw_base + ofs); } static inline u32 _il_rd(struct il_priv *il, u32 ofs) { - return ioread32(il->hw_base + ofs); + return readl(il->hw_base + ofs); } static inline void @@ -2209,6 +2025,13 @@ static inline void _il_release_nic_access(struct il_priv *il) { _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + /* + * In above we are reading CSR_GP_CNTRL register, what will flush any + * previous writes, but still want write, which clear MAC_ACCESS_REQ + * bit, be performed on PCI bus before any other writes scheduled on + * different CPUs (after we drop reg_lock). + */ + mmiowb(); } static inline u32 @@ -2231,7 +2054,7 @@ il_wr(struct il_priv *il, u32 reg, u32 value) unsigned long reg_flags; spin_lock_irqsave(&il->reg_lock, reg_flags); - if (!_il_grab_nic_access(il)) { + if (likely(_il_grab_nic_access(il))) { _il_wr(il, reg, value); _il_release_nic_access(il); } @@ -2242,7 +2065,6 @@ static inline u32 _il_rd_prph(struct il_priv *il, u32 reg) { _il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); - rmb(); return _il_rd(il, HBUS_TARG_PRPH_RDAT); } @@ -2250,7 +2072,6 @@ static inline void _il_wr_prph(struct il_priv *il, u32 addr, u32 val) { _il_wr(il, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24))); - wmb(); _il_wr(il, HBUS_TARG_PRPH_WDAT, val); } @@ -2260,9 +2081,10 @@ il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask) unsigned long reg_flags; spin_lock_irqsave(&il->reg_lock, reg_flags); - _il_grab_nic_access(il); - _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask)); - _il_release_nic_access(il); + if (likely(_il_grab_nic_access(il))) { + _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask)); + _il_release_nic_access(il); + } spin_unlock_irqrestore(&il->reg_lock, reg_flags); } @@ -2272,9 +2094,10 @@ il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask) unsigned long reg_flags; spin_lock_irqsave(&il->reg_lock, reg_flags); - _il_grab_nic_access(il); - _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits)); - _il_release_nic_access(il); + if (likely(_il_grab_nic_access(il))) { + _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits)); + _il_release_nic_access(il); + } spin_unlock_irqrestore(&il->reg_lock, reg_flags); } @@ -2285,10 +2108,11 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask) u32 val; spin_lock_irqsave(&il->reg_lock, reg_flags); - _il_grab_nic_access(il); - val = _il_rd_prph(il, reg); - _il_wr_prph(il, reg, (val & ~mask)); - _il_release_nic_access(il); + if (likely(_il_grab_nic_access(il))) { + val = _il_rd_prph(il, reg); + _il_wr_prph(il, reg, (val & ~mask)); + _il_release_nic_access(il); + } spin_unlock_irqrestore(&il->reg_lock, reg_flags); } @@ -2303,23 +2127,22 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask) (this is for the IBSS BSSID stations) */ #define IL_STA_BCAST BIT(4) /* this station is the special bcast station */ -void il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx); -void il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx); +void il_restore_stations(struct il_priv *il); +void il_clear_ucode_stations(struct il_priv *il); void il_dealloc_bcast_stations(struct il_priv *il); int il_get_free_ucode_key_idx(struct il_priv *il); int il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags); -int il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, +int il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap, struct ieee80211_sta *sta, u8 *sta_id_r); int il_remove_station(struct il_priv *il, const u8 sta_id, const u8 * addr); int il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx, - const u8 *addr, bool is_ap, struct ieee80211_sta *sta); +u8 il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap, + struct ieee80211_sta *sta); -int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx, - struct il_link_quality_cmd *lq, u8 flags, bool init); +int il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq, + u8 flags, bool init); /** * il_clear_driver_stations - clear knowledge of all stations from driver @@ -2334,24 +2157,11 @@ static inline void il_clear_driver_stations(struct il_priv *il) { unsigned long flags; - struct il_rxon_context *ctx = &il->ctx; spin_lock_irqsave(&il->sta_lock, flags); memset(il->stations, 0, sizeof(il->stations)); il->num_stations = 0; - il->ucode_key_table = 0; - - /* - * Remove all key information that is not stored as part - * of station information since mac80211 may not have had - * a chance to remove all the keys. When device is - * reconfigured by mac80211 after an error all keys will - * be reconfigured. - */ - memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); - ctx->key_mapping_keys = 0; - spin_unlock_irqrestore(&il->sta_lock, flags); } @@ -2376,13 +2186,12 @@ il_sta_id(struct ieee80211_sta *sta) * inline wraps that pattern. */ static inline int -il_sta_id_or_broadcast(struct il_priv *il, struct il_rxon_context *context, - struct ieee80211_sta *sta) +il_sta_id_or_broadcast(struct il_priv *il, struct ieee80211_sta *sta) { int sta_id; if (!sta) - return context->bcast_sta_id; + return il->hw_params.bcast_id; sta_id = il_sta_id(sta); @@ -2565,10 +2374,10 @@ struct il_rb_status { __le32 __unused; /* 3945 only */ } __packed; -#define TFD_QUEUE_SIZE_MAX (256) -#define TFD_QUEUE_SIZE_BC_DUP (64) +#define TFD_QUEUE_SIZE_MAX 256 +#define TFD_QUEUE_SIZE_BC_DUP 64 #define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP) -#define IL_TX_DMA_MASK DMA_BIT_MASK(36) +#define IL_TX_DMA_MASK DMA_BIT_MASK(36) #define IL_NUM_OF_TBS 20 static inline u8 diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index b1b8926a9c7..229849150aa 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -31,6 +31,101 @@ #include "common.h" +void +il_clear_traffic_stats(struct il_priv *il) +{ + memset(&il->tx_stats, 0, sizeof(struct traffic_stats)); + memset(&il->rx_stats, 0, sizeof(struct traffic_stats)); +} + +/* + * il_update_stats function record all the MGMT, CTRL and DATA pkt for + * both TX and Rx . Use debugfs to display the rx/rx_stats + */ +void +il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) +{ + struct traffic_stats *stats; + + if (is_tx) + stats = &il->tx_stats; + else + stats = &il->rx_stats; + + if (ieee80211_is_mgmt(fc)) { + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): + stats->mgmt[MANAGEMENT_ASSOC_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): + stats->mgmt[MANAGEMENT_ASSOC_RESP]++; + break; + case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + stats->mgmt[MANAGEMENT_REASSOC_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): + stats->mgmt[MANAGEMENT_REASSOC_RESP]++; + break; + case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): + stats->mgmt[MANAGEMENT_PROBE_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): + stats->mgmt[MANAGEMENT_PROBE_RESP]++; + break; + case cpu_to_le16(IEEE80211_STYPE_BEACON): + stats->mgmt[MANAGEMENT_BEACON]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ATIM): + stats->mgmt[MANAGEMENT_ATIM]++; + break; + case cpu_to_le16(IEEE80211_STYPE_DISASSOC): + stats->mgmt[MANAGEMENT_DISASSOC]++; + break; + case cpu_to_le16(IEEE80211_STYPE_AUTH): + stats->mgmt[MANAGEMENT_AUTH]++; + break; + case cpu_to_le16(IEEE80211_STYPE_DEAUTH): + stats->mgmt[MANAGEMENT_DEAUTH]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ACTION): + stats->mgmt[MANAGEMENT_ACTION]++; + break; + } + } else if (ieee80211_is_ctl(fc)) { + switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { + case cpu_to_le16(IEEE80211_STYPE_BACK_REQ): + stats->ctrl[CONTROL_BACK_REQ]++; + break; + case cpu_to_le16(IEEE80211_STYPE_BACK): + stats->ctrl[CONTROL_BACK]++; + break; + case cpu_to_le16(IEEE80211_STYPE_PSPOLL): + stats->ctrl[CONTROL_PSPOLL]++; + break; + case cpu_to_le16(IEEE80211_STYPE_RTS): + stats->ctrl[CONTROL_RTS]++; + break; + case cpu_to_le16(IEEE80211_STYPE_CTS): + stats->ctrl[CONTROL_CTS]++; + break; + case cpu_to_le16(IEEE80211_STYPE_ACK): + stats->ctrl[CONTROL_ACK]++; + break; + case cpu_to_le16(IEEE80211_STYPE_CFEND): + stats->ctrl[CONTROL_CFEND]++; + break; + case cpu_to_le16(IEEE80211_STYPE_CFENDACK): + stats->ctrl[CONTROL_CFENDACK]++; + break; + } + } else { + /* data */ + stats->data_cnt++; + stats->data_bytes += len; + } +} +EXPORT_SYMBOL(il_update_stats); + /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ if (!debugfs_create_file(#name, mode, parent, il, \ @@ -98,6 +193,46 @@ static const struct file_operations il_dbgfs_##name##_ops = { \ .llseek = generic_file_llseek, \ }; +static const char * +il_get_mgmt_string(int cmd) +{ + switch (cmd) { + IL_CMD(MANAGEMENT_ASSOC_REQ); + IL_CMD(MANAGEMENT_ASSOC_RESP); + IL_CMD(MANAGEMENT_REASSOC_REQ); + IL_CMD(MANAGEMENT_REASSOC_RESP); + IL_CMD(MANAGEMENT_PROBE_REQ); + IL_CMD(MANAGEMENT_PROBE_RESP); + IL_CMD(MANAGEMENT_BEACON); + IL_CMD(MANAGEMENT_ATIM); + IL_CMD(MANAGEMENT_DISASSOC); + IL_CMD(MANAGEMENT_AUTH); + IL_CMD(MANAGEMENT_DEAUTH); + IL_CMD(MANAGEMENT_ACTION); + default: + return "UNKNOWN"; + + } +} + +static const char * +il_get_ctrl_string(int cmd) +{ + switch (cmd) { + IL_CMD(CONTROL_BACK_REQ); + IL_CMD(CONTROL_BACK); + IL_CMD(CONTROL_PSPOLL); + IL_CMD(CONTROL_RTS); + IL_CMD(CONTROL_CTS); + IL_CMD(CONTROL_ACK); + IL_CMD(CONTROL_CFEND); + IL_CMD(CONTROL_CFENDACK); + default: + return "UNKNOWN"; + + } +} + static ssize_t il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -361,7 +496,7 @@ il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count, const u8 *ptr; char *buf; u16 eeprom_ver; - size_t eeprom_len = il->cfg->base_params->eeprom_size; + size_t eeprom_len = il->cfg->eeprom_size; buf_size = 4 * eeprom_len + 256; if (eeprom_len % 16) { @@ -495,8 +630,8 @@ il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count, scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n", test_bit(S_INT_ENABLED, &il->status)); pos += - scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n", - test_bit(S_RF_KILL_HW, &il->status)); + scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n", + test_bit(S_RFKILL, &il->status)); pos += scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n", test_bit(S_CT_KILL, &il->status)); @@ -644,12 +779,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - struct il_rxon_context *ctx = &il->ctx; int pos = 0, i; char buf[256]; const size_t bufsz = sizeof(buf); - pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", ctx->ctxid); for (i = 0; i < AC_NUM; i++) { pos += scnprintf(buf + pos, bufsz - pos, @@ -657,10 +790,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, pos += scnprintf(buf + pos, bufsz - pos, "AC[%d]\t%u\t%u\t%u\t%u\n", i, - ctx->qos_data.def_qos_parm.ac[i].cw_min, - ctx->qos_data.def_qos_parm.ac[i].cw_max, - ctx->qos_data.def_qos_parm.ac[i].aifsn, - ctx->qos_data.def_qos_parm.ac[i].edca_txop); + il->qos_data.def_qos_parm.ac[i].cw_min, + il->qos_data.def_qos_parm.ac[i].cw_max, + il->qos_data.def_qos_parm.ac[i].aifsn, + il->qos_data.def_qos_parm.ac[i].edca_txop); } return simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -717,112 +850,6 @@ DEBUGFS_READ_FILE_OPS(qos); DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); static ssize_t -il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct il_priv *il = file->private_data; - int pos = 0, ofs = 0; - int cnt = 0, entry; - struct il_tx_queue *txq; - struct il_queue *q; - struct il_rx_queue *rxq = &il->rxq; - char *buf; - int bufsz = - ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (il->cfg->base_params->num_of_queues * 32 * 8) + 400; - const u8 *ptr; - ssize_t ret; - - if (!il->txq) { - IL_ERR("txq not ready\n"); - return -EAGAIN; - } - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) { - IL_ERR("Can not allocate buffer\n"); - return -ENOMEM; - } - pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); - for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { - txq = &il->txq[cnt]; - q = &txq->q; - pos += - scnprintf(buf + pos, bufsz - pos, - "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt, - q->read_ptr, q->write_ptr); - } - if (il->tx_traffic && (il_debug_level & IL_DL_TX)) { - ptr = il->tx_traffic; - pos += - scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n", - il->tx_traffic_idx); - for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) { - for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16; - entry++, ofs += 16) { - pos += - scnprintf(buf + pos, bufsz - pos, "0x%.4x ", - ofs); - hex_dump_to_buffer(ptr + ofs, 16, 16, 2, - buf + pos, bufsz - pos, 0); - pos += strlen(buf + pos); - if (bufsz - pos > 0) - buf[pos++] = '\n'; - } - } - } - - pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); - pos += - scnprintf(buf + pos, bufsz - pos, "read: %u, write: %u\n", - rxq->read, rxq->write); - - if (il->rx_traffic && (il_debug_level & IL_DL_RX)) { - ptr = il->rx_traffic; - pos += - scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n", - il->rx_traffic_idx); - for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) { - for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16; - entry++, ofs += 16) { - pos += - scnprintf(buf + pos, bufsz - pos, "0x%.4x ", - ofs); - hex_dump_to_buffer(ptr + ofs, 16, 16, 2, - buf + pos, bufsz - pos, 0); - pos += strlen(buf + pos); - if (bufsz - pos > 0) - buf[pos++] = '\n'; - } - } - } - - ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); - kfree(buf); - return ret; -} - -static ssize_t -il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct il_priv *il = file->private_data; - char buf[8]; - int buf_size; - int traffic_log; - - 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", &traffic_log) != 1) - return -EFAULT; - if (traffic_log == 0) - il_reset_traffic_log(il); - - return count; -} - -static ssize_t il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -835,7 +862,7 @@ il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count, int cnt; int ret; const size_t bufsz = - sizeof(char) * 64 * il->cfg->base_params->num_of_queues; + sizeof(char) * 64 * il->cfg->num_of_queues; if (!il->txq) { IL_ERR("txq not ready\n"); @@ -903,8 +930,8 @@ il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf, - count, ppos); + + return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos); } static ssize_t @@ -912,8 +939,8 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf, - count, ppos); + + return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos); } static ssize_t @@ -921,8 +948,8 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct il_priv *il = file->private_data; - return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf, - count, ppos); + + return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos); } static ssize_t @@ -1153,7 +1180,7 @@ il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, int len = 0; char buf[20]; - len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.flags)); + len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1167,7 +1194,7 @@ il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf, char buf[20]; len = - sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.filter_flags)); + sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1180,8 +1207,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count, int pos = 0; ssize_t ret = -EFAULT; - if (il->cfg->ops->lib->dump_fh) { - ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true); + if (il->ops->dump_fh) { + ret = pos = il->ops->dump_fh(il, &buf, true); if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, @@ -1298,14 +1325,13 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf, if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT) timeout = IL_DEF_WD_TIMEOUT; - il->cfg->base_params->wd_timeout = timeout; + il->cfg->wd_timeout = timeout; il_setup_watchdog(il); return count; } DEBUGFS_READ_FILE_OPS(rx_stats); DEBUGFS_READ_FILE_OPS(tx_stats); -DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); DEBUGFS_READ_FILE_OPS(rx_queue); DEBUGFS_READ_FILE_OPS(tx_queue); DEBUGFS_READ_FILE_OPS(ucode_rx_stats); @@ -1359,7 +1385,6 @@ il_dbgfs_register(struct il_priv *il, const char *name) DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR); - DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); @@ -1372,17 +1397,17 @@ il_dbgfs_register(struct il_priv *il, const char *name) DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); - if (il->cfg->base_params->sensitivity_calib_by_driver) + if (il->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); - if (il->cfg->base_params->chain_noise_calib_by_driver) + if (il->cfg->chain_noise_calib_by_driver) DEBUGFS_ADD_FILE(chain_noise, dir_debug, 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); - if (il->cfg->base_params->sensitivity_calib_by_driver) + if (il->cfg->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &il->disable_sens_cal); - if (il->cfg->base_params->chain_noise_calib_by_driver) + if (il->cfg->chain_noise_calib_by_driver) DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &il->disable_chain_noise_cal); DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal); diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ae08498dfca..2fe62730ddd 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,6 +1,6 @@ config IWLWIFI tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " - depends on PCI && MAC80211 + depends on PCI && MAC80211 && HAS_IOMEM select FW_LOADER select NEW_LEDS select LEDS_CLASS @@ -127,3 +127,12 @@ config IWLWIFI_P2P support when it is loaded. Say Y only if you want to experiment with P2P. + +config IWLWIFI_EXPERIMENTAL_MFP + bool "support MFP (802.11w) even if uCode doesn't advertise" + depends on IWLWIFI + help + This option enables experimental MFP (802.11W) support + even if the microcode doesn't advertise it. + + Say Y only if you want to experiment with MFP. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 9dc84a7354d..85d163ed3db 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,7 +1,7 @@ # WIFI obj-$(CONFIG_IWLWIFI) += iwlwifi.o iwlwifi-objs := iwl-agn.o iwl-agn-rs.o iwl-mac80211.o -iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o +iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwl-debug.o iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o @@ -13,7 +13,8 @@ iwlwifi-objs += iwl-6000.o iwlwifi-objs += iwl-1000.o iwlwifi-objs += iwl-2000.o iwlwifi-objs += iwl-pci.o -iwlwifi-objs += iwl-trans.o +iwlwifi-objs += iwl-drv.o +iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 1ef7bfc2ab2..5b0d888f746 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -43,6 +43,7 @@ #include "iwl-agn-hw.h" #include "iwl-shared.h" #include "iwl-cfg.h" +#include "iwl-prph.h" /* Highest firmware API version supported */ #define IWL1000_UCODE_API_MAX 6 @@ -84,20 +85,19 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) static void iwl1000_nic_config(struct iwl_priv *priv) { /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); /* Setting digital SVR for 1000 card to 1.32V */ /* locking is acquired in iwl_set_bits_mask_prph() function */ - iwl_set_bits_mask_prph(bus(priv), APMG_DIGITAL_SVR_REG, + iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG, APMG_SVR_DIGITAL_VOLTAGE_1_32, ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); } -static struct iwl_sensitivity_ranges iwl1000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl1000_sensitivity = { .min_nrg_cck = 95, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 90, .auto_corr_min_ofdm_mrc = 170, .auto_corr_min_ofdm_x1 = 120, @@ -120,36 +120,22 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = { .nrg_th_cca = 62, }; -static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) +static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; - hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); if (cfg(priv)->rx_with_siso_diversity) hw_params(priv).rx_chains_num = 1; else hw_params(priv).rx_chains_num = - num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + num_of_ant(hw_params(priv).valid_rx_ant); iwl1000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ hw_params(priv).sens = &iwl1000_sensitivity; - - return 0; } static struct iwl_lib_ops iwl1000_lib = { @@ -169,7 +155,7 @@ static struct iwl_lib_ops iwl1000_lib = { .temperature = iwlagn_temperature, }; -static struct iwl_base_params iwl1000_base_params = { +static const struct iwl_base_params iwl1000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .eeprom_size = OTP_LOW_IMAGE_SIZE, @@ -184,7 +170,8 @@ static struct iwl_base_params iwl1000_base_params = { .max_event_log_size = 128, .wd_disable = true, }; -static struct iwl_ht_params iwl1000_ht_params = { + +static const struct iwl_ht_params iwl1000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ .smps_mode = IEEE80211_SMPS_DYNAMIC, @@ -195,19 +182,21 @@ static struct iwl_ht_params iwl1000_ht_params = { .ucode_api_max = IWL1000_UCODE_API_MAX, \ .ucode_api_ok = IWL1000_UCODE_API_OK, \ .ucode_api_min = IWL1000_UCODE_API_MIN, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ .lib = &iwl1000_lib, \ .base_params = &iwl1000_base_params, \ .led_mode = IWL_LED_BLINK -struct iwl_cfg iwl1000_bgn_cfg = { +const struct iwl_cfg iwl1000_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", IWL_DEVICE_1000, .ht_params = &iwl1000_ht_params, }; -struct iwl_cfg iwl1000_bg_cfg = { +const struct iwl_cfg iwl1000_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", IWL_DEVICE_1000, }; @@ -217,6 +206,8 @@ struct iwl_cfg iwl1000_bg_cfg = { .ucode_api_max = IWL100_UCODE_API_MAX, \ .ucode_api_ok = IWL100_UCODE_API_OK, \ .ucode_api_min = IWL100_UCODE_API_MIN, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_1000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ .lib = &iwl1000_lib, \ @@ -224,13 +215,13 @@ struct iwl_cfg iwl1000_bg_cfg = { .led_mode = IWL_LED_RF_STATE, \ .rx_with_siso_diversity = true -struct iwl_cfg iwl100_bgn_cfg = { +const struct iwl_cfg iwl100_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", IWL_DEVICE_100, .ht_params = &iwl1000_ht_params, }; -struct iwl_cfg iwl100_bg_cfg = { +const struct iwl_cfg iwl100_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 100 BG", IWL_DEVICE_100, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 094693328db..5635b9e2c69 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -87,13 +87,12 @@ static void iwl2000_nic_config(struct iwl_priv *priv) iwl_rf_config(priv); if (cfg(priv)->iq_invert) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); } -static struct iwl_sensitivity_ranges iwl2000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl2000_sensitivity = { .min_nrg_cck = 97, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 80, .auto_corr_min_ofdm_mrc = 128, .auto_corr_min_ofdm_x1 = 105, @@ -116,36 +115,22 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = { .nrg_th_cca = 62, }; -static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) +static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - - hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; - hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); if (cfg(priv)->rx_with_siso_diversity) hw_params(priv).rx_chains_num = 1; else hw_params(priv).rx_chains_num = - num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + num_of_ant(hw_params(priv).valid_rx_ant); iwl2000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ hw_params(priv).sens = &iwl2000_sensitivity; - - return 0; } static struct iwl_lib_ops iwl2000_lib = { @@ -161,16 +146,13 @@ static struct iwl_lib_ops iwl2000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REGULATORY_BAND_NO_HT40, }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; static struct iwl_lib_ops iwl2030_lib = { .set_hw_params = iwl2000_hw_set_hw_params, - .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, - .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, - .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .nic_config = iwl2000_nic_config, .eeprom_ops = { .regulatory_bands = { @@ -182,12 +164,12 @@ static struct iwl_lib_ops iwl2030_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REGULATORY_BAND_NO_HT40, }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; -static struct iwl_base_params iwl2000_base_params = { +static const struct iwl_base_params iwl2000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -206,7 +188,7 @@ static struct iwl_base_params iwl2000_base_params = { }; -static struct iwl_base_params iwl2030_base_params = { +static const struct iwl_base_params iwl2030_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -224,12 +206,12 @@ static struct iwl_base_params iwl2030_base_params = { .hd_v2 = true, }; -static struct iwl_ht_params iwl2000_ht_params = { +static const struct iwl_ht_params iwl2000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ }; -static struct iwl_bt_params iwl2030_bt_params = { +static const struct iwl_bt_params iwl2030_bt_params = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, .agg_time_limit = BT_AGG_THRESHOLD_DEF, @@ -244,6 +226,8 @@ static struct iwl_bt_params iwl2030_bt_params = { .ucode_api_max = IWL2000_UCODE_API_MAX, \ .ucode_api_ok = IWL2000_UCODE_API_OK, \ .ucode_api_min = IWL2000_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .lib = &iwl2000_lib, \ @@ -253,13 +237,13 @@ static struct iwl_bt_params iwl2030_bt_params = { .led_mode = IWL_LED_RF_STATE, \ .iq_invert = true \ -struct iwl_cfg iwl2000_2bgn_cfg = { +const struct iwl_cfg iwl2000_2bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", IWL_DEVICE_2000, .ht_params = &iwl2000_ht_params, }; -struct iwl_cfg iwl2000_2bgn_d_cfg = { +const struct iwl_cfg iwl2000_2bgn_d_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", IWL_DEVICE_2000, .ht_params = &iwl2000_ht_params, @@ -270,6 +254,8 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { .ucode_api_max = IWL2030_UCODE_API_MAX, \ .ucode_api_ok = IWL2030_UCODE_API_OK, \ .ucode_api_min = IWL2030_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .lib = &iwl2030_lib, \ @@ -281,7 +267,7 @@ struct iwl_cfg iwl2000_2bgn_d_cfg = { .adv_pm = true, \ .iq_invert = true \ -struct iwl_cfg iwl2030_2bgn_cfg = { +const struct iwl_cfg iwl2030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", IWL_DEVICE_2030, .ht_params = &iwl2000_ht_params, @@ -292,6 +278,8 @@ struct iwl_cfg iwl2030_2bgn_cfg = { .ucode_api_max = IWL105_UCODE_API_MAX, \ .ucode_api_ok = IWL105_UCODE_API_OK, \ .ucode_api_min = IWL105_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .lib = &iwl2000_lib, \ @@ -303,13 +291,13 @@ struct iwl_cfg iwl2030_2bgn_cfg = { .rx_with_siso_diversity = true, \ .iq_invert = true \ -struct iwl_cfg iwl105_bgn_cfg = { +const struct iwl_cfg iwl105_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", IWL_DEVICE_105, .ht_params = &iwl2000_ht_params, }; -struct iwl_cfg iwl105_bgn_d_cfg = { +const struct iwl_cfg iwl105_bgn_d_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", IWL_DEVICE_105, .ht_params = &iwl2000_ht_params, @@ -320,6 +308,8 @@ struct iwl_cfg iwl105_bgn_d_cfg = { .ucode_api_max = IWL135_UCODE_API_MAX, \ .ucode_api_ok = IWL135_UCODE_API_OK, \ .ucode_api_min = IWL135_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_2000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ .lib = &iwl2030_lib, \ @@ -332,7 +322,7 @@ struct iwl_cfg iwl105_bgn_d_cfg = { .rx_with_siso_diversity = true, \ .iq_invert = true \ -struct iwl_cfg iwl135_bgn_cfg = { +const struct iwl_cfg iwl135_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", IWL_DEVICE_135, .ht_params = &iwl2000_ht_params, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index b3a365fea7b..a805e97b89a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -45,6 +45,7 @@ #include "iwl-trans.h" #include "iwl-shared.h" #include "iwl-cfg.h" +#include "iwl-prph.h" /* Highest firmware API version supported */ #define IWL5000_UCODE_API_MAX 5 @@ -63,27 +64,19 @@ /* NIC configuration for 5000 series */ static void iwl5000_nic_config(struct iwl_priv *priv) { - unsigned long flags; - iwl_rf_config(priv); - spin_lock_irqsave(&priv->shrd->lock, flags); - /* 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. */ - iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); - - - spin_unlock_irqrestore(&priv->shrd->lock, flags); } -static struct iwl_sensitivity_ranges iwl5000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl5000_sensitivity = { .min_nrg_cck = 100, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 90, .auto_corr_min_ofdm_mrc = 170, .auto_corr_min_ofdm_x1 = 105, @@ -108,7 +101,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { static struct iwl_sensitivity_ranges iwl5150_sensitivity = { .min_nrg_cck = 95, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 90, .auto_corr_min_ofdm_mrc = 170, .auto_corr_min_ofdm_x1 = 105, @@ -162,62 +154,36 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) hw_params(priv).ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY; } -static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) +static void iwl5000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; - hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); - hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); + hw_params(priv).rx_chains_num = + num_of_ant(hw_params(priv).valid_rx_ant); iwl5000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ hw_params(priv).sens = &iwl5000_sensitivity; - - return 0; } -static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) +static void iwl5150_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; - hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); - hw_params(priv).rx_chains_num = num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); + hw_params(priv).rx_chains_num = + num_of_ant(hw_params(priv).valid_rx_ant); iwl5150_set_ct_threshold(priv); /* Set initial sensitivity parameters */ hw_params(priv).sens = &iwl5150_sensitivity; - - return 0; } static void iwl5150_temperature(struct iwl_priv *priv) @@ -300,7 +266,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return iwl_trans_send_cmd(trans(priv), &hcmd); + return iwl_dvm_send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl5000_lib = { @@ -339,7 +305,7 @@ static struct iwl_lib_ops iwl5150_lib = { .temperature = iwl5150_temperature, }; -static struct iwl_base_params iwl5000_base_params = { +static const struct iwl_base_params iwl5000_base_params = { .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -352,7 +318,8 @@ static struct iwl_base_params iwl5000_base_params = { .no_idle_support = true, .wd_disable = true, }; -static struct iwl_ht_params iwl5000_ht_params = { + +static const struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, }; @@ -360,13 +327,15 @@ static struct iwl_ht_params iwl5000_ht_params = { .fw_name_pre = IWL5000_FW_PRE, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \ .ucode_api_min = IWL5000_UCODE_API_MIN, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_5000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ .lib = &iwl5000_lib, \ .base_params = &iwl5000_base_params, \ .led_mode = IWL_LED_BLINK -struct iwl_cfg iwl5300_agn_cfg = { +const struct iwl_cfg iwl5300_agn_cfg = { .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", IWL_DEVICE_5000, /* at least EEPROM 0x11A has wrong info */ @@ -375,7 +344,7 @@ struct iwl_cfg iwl5300_agn_cfg = { .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5100_bgn_cfg = { +const struct iwl_cfg iwl5100_bgn_cfg = { .name = "Intel(R) WiFi Link 5100 BGN", IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ @@ -383,14 +352,14 @@ struct iwl_cfg iwl5100_bgn_cfg = { .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5100_abg_cfg = { +const struct iwl_cfg iwl5100_abg_cfg = { .name = "Intel(R) WiFi Link 5100 ABG", IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ }; -struct iwl_cfg iwl5100_agn_cfg = { +const struct iwl_cfg iwl5100_agn_cfg = { .name = "Intel(R) WiFi Link 5100 AGN", IWL_DEVICE_5000, .valid_tx_ant = ANT_B, /* .cfg overwrite */ @@ -398,11 +367,13 @@ struct iwl_cfg iwl5100_agn_cfg = { .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5350_agn_cfg = { +const struct iwl_cfg iwl5350_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, + .max_inst_size = IWLAGN_RTC_INST_SIZE, + .max_data_size = IWLAGN_RTC_DATA_SIZE, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, .lib = &iwl5000_lib, @@ -416,6 +387,8 @@ struct iwl_cfg iwl5350_agn_cfg = { .fw_name_pre = IWL5150_FW_PRE, \ .ucode_api_max = IWL5150_UCODE_API_MAX, \ .ucode_api_min = IWL5150_UCODE_API_MIN, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_5050_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ .lib = &iwl5150_lib, \ @@ -424,14 +397,14 @@ struct iwl_cfg iwl5350_agn_cfg = { .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -struct iwl_cfg iwl5150_agn_cfg = { +const struct iwl_cfg iwl5150_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", IWL_DEVICE_5150, .ht_params = &iwl5000_ht_params, }; -struct iwl_cfg iwl5150_abg_cfg = { +const struct iwl_cfg iwl5150_abg_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", IWL_DEVICE_5150, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 54b753399e6..64060cd738b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -82,7 +82,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (iwl_eeprom_calib_version(priv->shrd) >= 6) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } @@ -90,31 +90,31 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (iwl_eeprom_calib_version(priv->shrd) >= 6) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_6050_1x2); } +static void iwl6000i_additional_nic_config(struct iwl_priv *priv) +{ + /* 2x2 IPA phy type */ + iwl_write32(trans(priv), CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); +} + /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { iwl_rf_config(priv); - /* no locking required for register write */ - if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { - /* 2x2 IPA phy type */ - iwl_write32(bus(priv), CSR_GP_DRIVER_REG, - CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); - } /* do additional nic configuration if needed */ if (cfg(priv)->additional_nic_config) - cfg(priv)->additional_nic_config(priv); + cfg(priv)->additional_nic_config(priv); } -static struct iwl_sensitivity_ranges iwl6000_sensitivity = { +static const struct iwl_sensitivity_ranges iwl6000_sensitivity = { .min_nrg_cck = 110, - .max_nrg_cck = 0, /* not used, set to 0 */ .auto_corr_min_ofdm = 80, .auto_corr_min_ofdm_mrc = 128, .auto_corr_min_ofdm_x1 = 105, @@ -137,37 +137,24 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { .nrg_th_cca = 62, }; -static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) +static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) { - if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && - iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) - cfg(priv)->base_params->num_of_queues = - iwlagn_mod_params.num_of_queues; - - hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - - hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; - hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; - hw_params(priv).ht40_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); - hw_params(priv).tx_chains_num = num_of_ant(cfg(priv)->valid_tx_ant); + hw_params(priv).tx_chains_num = + num_of_ant(hw_params(priv).valid_tx_ant); if (cfg(priv)->rx_with_siso_diversity) hw_params(priv).rx_chains_num = 1; else hw_params(priv).rx_chains_num = - num_of_ant(cfg(priv)->valid_rx_ant); - hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; - hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + num_of_ant(hw_params(priv).valid_rx_ant); iwl6000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ hw_params(priv).sens = &iwl6000_sensitivity; - return 0; } static int iwl6000_hw_channel_switch(struct iwl_priv *priv, @@ -238,7 +225,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return -EFAULT; } - return iwl_trans_send_cmd(trans(priv), &hcmd); + return iwl_dvm_send_cmd(priv, &hcmd); } static struct iwl_lib_ops iwl6000_lib = { @@ -255,16 +242,13 @@ static struct iwl_lib_ops iwl6000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; static struct iwl_lib_ops iwl6030_lib = { .set_hw_params = iwl6000_hw_set_hw_params, - .bt_rx_handler_setup = iwlagn_bt_rx_handler_setup, - .bt_setup_deferred_work = iwlagn_bt_setup_deferred_work, - .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, .set_channel_switch = iwl6000_hw_channel_switch, .nic_config = iwl6000_nic_config, .eeprom_ops = { @@ -277,12 +261,12 @@ static struct iwl_lib_ops iwl6030_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .update_enhanced_txpower = iwl_eeprom_enhanced_txpower, + .enhanced_txpower = true, }, .temperature = iwlagn_temperature, }; -static struct iwl_base_params iwl6000_base_params = { +static const struct iwl_base_params iwl6000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -299,7 +283,7 @@ static struct iwl_base_params iwl6000_base_params = { .shadow_reg_enable = true, }; -static struct iwl_base_params iwl6050_base_params = { +static const struct iwl_base_params iwl6050_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -315,7 +299,8 @@ static struct iwl_base_params iwl6050_base_params = { .max_event_log_size = 1024, .shadow_reg_enable = true, }; -static struct iwl_base_params iwl6000_g2_base_params = { + +static const struct iwl_base_params iwl6000_g2_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, @@ -332,12 +317,12 @@ static struct iwl_base_params iwl6000_g2_base_params = { .shadow_reg_enable = true, }; -static struct iwl_ht_params iwl6000_ht_params = { +static const struct iwl_ht_params iwl6000_ht_params = { .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ }; -static struct iwl_bt_params iwl6000_bt_params = { +static const struct iwl_bt_params iwl6000_bt_params = { /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, .agg_time_limit = BT_AGG_THRESHOLD_DEF, @@ -351,6 +336,8 @@ static struct iwl_bt_params iwl6000_bt_params = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_6005_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ .lib = &iwl6000_lib, \ @@ -358,39 +345,53 @@ static struct iwl_bt_params iwl6000_bt_params = { .need_temp_offset_calib = true, \ .led_mode = IWL_LED_RF_STATE -struct iwl_cfg iwl6005_2agn_cfg = { +const struct iwl_cfg iwl6005_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6005_2abg_cfg = { +const struct iwl_cfg iwl6005_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", IWL_DEVICE_6005, }; -struct iwl_cfg iwl6005_2bg_cfg = { +const struct iwl_cfg iwl6005_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", IWL_DEVICE_6005, }; -struct iwl_cfg iwl6005_2agn_sff_cfg = { +const struct iwl_cfg iwl6005_2agn_sff_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6005_2agn_d_cfg = { +const struct iwl_cfg iwl6005_2agn_d_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", IWL_DEVICE_6005, .ht_params = &iwl6000_ht_params, }; +const struct iwl_cfg iwl6005_2agn_mow1_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_mow2_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + #define IWL_DEVICE_6030 \ .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .eeprom_ver = EEPROM_6030_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ .lib = &iwl6030_lib, \ @@ -400,53 +401,53 @@ struct iwl_cfg iwl6005_2agn_d_cfg = { .led_mode = IWL_LED_RF_STATE, \ .adv_pm = true \ -struct iwl_cfg iwl6030_2agn_cfg = { +const struct iwl_cfg iwl6030_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6030_2abg_cfg = { +const struct iwl_cfg iwl6030_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", IWL_DEVICE_6030, }; -struct iwl_cfg iwl6030_2bgn_cfg = { +const struct iwl_cfg iwl6030_2bgn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6030_2bg_cfg = { +const struct iwl_cfg iwl6030_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", IWL_DEVICE_6030, }; -struct iwl_cfg iwl6035_2agn_cfg = { +const struct iwl_cfg iwl6035_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl1030_bgn_cfg = { +const struct iwl_cfg iwl1030_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl1030_bg_cfg = { +const struct iwl_cfg iwl1030_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", IWL_DEVICE_6030, }; -struct iwl_cfg iwl130_bgn_cfg = { +const struct iwl_cfg iwl130_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", IWL_DEVICE_6030, .ht_params = &iwl6000_ht_params, .rx_with_siso_diversity = true, }; -struct iwl_cfg iwl130_bg_cfg = { +const struct iwl_cfg iwl130_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 130 BG", IWL_DEVICE_6030, .rx_with_siso_diversity = true, @@ -460,27 +461,29 @@ struct iwl_cfg iwl130_bg_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, \ .ucode_api_ok = IWL6000_UCODE_API_OK, \ .ucode_api_min = IWL6000_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ .eeprom_ver = EEPROM_6000_EEPROM_VERSION, \ .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ .lib = &iwl6000_lib, \ + .additional_nic_config = iwl6000i_additional_nic_config,\ .base_params = &iwl6000_base_params, \ - .pa_type = IWL_PA_INTERNAL, \ .led_mode = IWL_LED_BLINK -struct iwl_cfg iwl6000i_2agn_cfg = { +const struct iwl_cfg iwl6000i_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", IWL_DEVICE_6000i, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6000i_2abg_cfg = { +const struct iwl_cfg iwl6000i_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", IWL_DEVICE_6000i, }; -struct iwl_cfg iwl6000i_2bg_cfg = { +const struct iwl_cfg iwl6000i_2bg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", IWL_DEVICE_6000i, }; @@ -489,6 +492,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .fw_name_pre = IWL6050_FW_PRE, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ .lib = &iwl6000_lib, \ @@ -499,13 +504,13 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -struct iwl_cfg iwl6050_2agn_cfg = { +const struct iwl_cfg iwl6050_2agn_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", IWL_DEVICE_6050, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6050_2abg_cfg = { +const struct iwl_cfg iwl6050_2abg_cfg = { .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", IWL_DEVICE_6050, }; @@ -514,6 +519,8 @@ struct iwl_cfg iwl6050_2abg_cfg = { .fw_name_pre = IWL6050_FW_PRE, \ .ucode_api_max = IWL6050_UCODE_API_MAX, \ .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ .lib = &iwl6000_lib, \ .additional_nic_config = iwl6150_additional_nic_config, \ .eeprom_ver = EEPROM_6150_EEPROM_VERSION, \ @@ -522,23 +529,25 @@ struct iwl_cfg iwl6050_2abg_cfg = { .led_mode = IWL_LED_BLINK, \ .internal_wimax_coex = true -struct iwl_cfg iwl6150_bgn_cfg = { +const struct iwl_cfg iwl6150_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", IWL_DEVICE_6150, .ht_params = &iwl6000_ht_params, }; -struct iwl_cfg iwl6150_bg_cfg = { +const struct iwl_cfg iwl6150_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", IWL_DEVICE_6150, }; -struct iwl_cfg iwl6000_3agn_cfg = { +const struct iwl_cfg iwl6000_3agn_cfg = { .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_ok = IWL6000_UCODE_API_OK, .ucode_api_min = IWL6000_UCODE_API_MIN, + .max_inst_size = IWL60_RTC_INST_SIZE, + .max_data_size = IWL60_RTC_DATA_SIZE, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, .lib = &iwl6000_lib, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 50ff849c9f6..84cbe7bb504 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -73,6 +73,14 @@ * INIT calibrations framework *****************************************************************************/ +/* Opaque calibration results */ +struct iwl_calib_result { + struct list_head list; + size_t cmd_len; + struct iwl_calib_hdr hdr; + /* data follows */ +}; + struct statistics_general_data { u32 beacon_silence_rssi_a; u32 beacon_silence_rssi_b; @@ -82,7 +90,7 @@ struct statistics_general_data { u32 beacon_energy_c; }; -int iwl_send_calib_results(struct iwl_trans *trans) +int iwl_send_calib_results(struct iwl_priv *priv) { struct iwl_host_cmd hcmd = { .id = REPLY_PHY_CALIBRATION_CMD, @@ -90,15 +98,15 @@ int iwl_send_calib_results(struct iwl_trans *trans) }; struct iwl_calib_result *res; - list_for_each_entry(res, &trans->calib_results, list) { + list_for_each_entry(res, &priv->calib_results, list) { int ret; hcmd.len[0] = res->cmd_len; hcmd.data[0] = &res->hdr; hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - ret = iwl_trans_send_cmd(trans, &hcmd); + ret = iwl_dvm_send_cmd(priv, &hcmd); if (ret) { - IWL_ERR(trans, "Error %d on calib cmd %d\n", + IWL_ERR(priv, "Error %d on calib cmd %d\n", ret, res->hdr.op_code); return ret; } @@ -107,7 +115,7 @@ int iwl_send_calib_results(struct iwl_trans *trans) return 0; } -int iwl_calib_set(struct iwl_trans *trans, +int iwl_calib_set(struct iwl_priv *priv, const struct iwl_calib_hdr *cmd, int len) { struct iwl_calib_result *res, *tmp; @@ -119,7 +127,7 @@ int iwl_calib_set(struct iwl_trans *trans, memcpy(&res->hdr, cmd, len); res->cmd_len = len; - list_for_each_entry(tmp, &trans->calib_results, list) { + list_for_each_entry(tmp, &priv->calib_results, list) { if (tmp->hdr.op_code == res->hdr.op_code) { list_replace(&tmp->list, &res->list); kfree(tmp); @@ -128,16 +136,16 @@ int iwl_calib_set(struct iwl_trans *trans, } /* wasn't in list already */ - list_add_tail(&res->list, &trans->calib_results); + list_add_tail(&res->list, &priv->calib_results); return 0; } -void iwl_calib_free_results(struct iwl_trans *trans) +void iwl_calib_free_results(struct iwl_priv *priv) { struct iwl_calib_result *res, *tmp; - list_for_each_entry_safe(res, tmp, &trans->calib_results, list) { + list_for_each_entry_safe(res, tmp, &priv->calib_results, list) { list_del(&res->list); kfree(res); } @@ -492,7 +500,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv) memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), sizeof(u16)*HD_TABLE_SIZE); - return iwl_trans_send_cmd(trans(priv), &cmd_out); + return iwl_dvm_send_cmd(priv, &cmd_out); } /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ @@ -581,7 +589,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) &(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]), sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES); - return iwl_trans_send_cmd(trans(priv), &cmd_out); + return iwl_dvm_send_cmd(priv, &cmd_out); } void iwl_init_sensitivity(struct iwl_priv *priv) @@ -634,7 +642,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv) data->last_bad_plcp_cnt_cck = 0; data->last_fa_cnt_cck = 0; - if (priv->enhance_sensitivity_table) + if (priv->fw->enhance_sensitivity_table) ret |= iwl_enhance_sensitivity_write(priv); else ret |= iwl_sensitivity_write(priv); @@ -653,7 +661,6 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) struct iwl_sensitivity_data *data = NULL; struct statistics_rx_non_phy *rx_info; struct statistics_rx_phy *ofdm, *cck; - unsigned long flags; struct statistics_general_data statis; if (priv->disable_sens_cal) @@ -666,13 +673,13 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) return; } - spin_lock_irqsave(&priv->shrd->lock, flags); + spin_lock_bh(&priv->statistics.lock); rx_info = &priv->statistics.rx_non_phy; ofdm = &priv->statistics.rx_ofdm; cck = &priv->statistics.rx_cck; if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, "<< invalid data.\n"); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); return; } @@ -696,7 +703,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) statis.beacon_energy_c = le32_to_cpu(rx_info->beacon_energy_c); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); IWL_DEBUG_CALIB(priv, "rx_enable_time = %u usecs\n", rx_enable_time); @@ -745,7 +752,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv) iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); - if (priv->enhance_sensitivity_table) + if (priv->fw->enhance_sensitivity_table) iwl_enhance_sensitivity_write(priv); else iwl_sensitivity_write(priv); @@ -847,7 +854,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, * connect the first valid tx chain */ first_chain = - find_first_chain(cfg(priv)->valid_tx_ant); + find_first_chain(hw_params(priv).valid_tx_ant); data->disconn_array[first_chain] = 0; active_chains |= BIT(first_chain); IWL_DEBUG_CALIB(priv, @@ -872,10 +879,8 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig, } static void iwlagn_gain_computation(struct iwl_priv *priv, - u32 average_noise[NUM_RX_CHAINS], - u16 min_average_noise_antenna_i, - u32 min_average_noise, - u8 default_chain) + u32 average_noise[NUM_RX_CHAINS], + u8 default_chain) { int i; s32 delta_g; @@ -923,7 +928,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, priv->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_trans_send_cmd_pdu(trans(priv), REPLY_PHY_CALIBRATION_CMD, + iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, CMD_ASYNC, sizeof(cmd), &cmd); data->radio_write = 1; @@ -956,7 +961,6 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) u16 stat_chnum = INITIALIZATION_VALUE; u8 rxon_band24; u8 stat_band24; - unsigned long flags; struct statistics_rx_non_phy *rx_info; /* @@ -981,13 +985,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) return; } - spin_lock_irqsave(&priv->shrd->lock, flags); + spin_lock_bh(&priv->statistics.lock); rx_info = &priv->statistics.rx_non_phy; if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) { IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n"); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); return; } @@ -1002,7 +1006,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) if ((rxon_chnum != stat_chnum) || (rxon_band24 != stat_band24)) { IWL_DEBUG_CALIB(priv, "Stats not from chan=%d, band24=%d\n", rxon_chnum, rxon_band24); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); return; } @@ -1021,7 +1025,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) chain_sig_b = le32_to_cpu(rx_info->beacon_rssi_b) & IN_BAND_FILTER; chain_sig_c = le32_to_cpu(rx_info->beacon_rssi_c) & IN_BAND_FILTER; - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock_bh(&priv->statistics.lock); data->beacon_count++; @@ -1081,8 +1085,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) min_average_noise, min_average_noise_antenna_i); iwlagn_gain_computation(priv, average_noise, - min_average_noise_antenna_i, min_average_noise, - find_first_chain(cfg(priv)->valid_rx_ant)); + find_first_chain(hw_params(priv).valid_rx_ant)); /* Some power changes may have been made during the calibration. * Update and commit the RXON diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index 10275ce92bd..9ed6683314a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 123ef5e129d..d0ec0abd3c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ca78e91de86..56f41c9409d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -32,7 +32,6 @@ #include <linux/init.h> #include <linux/sched.h> -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" @@ -52,7 +51,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) struct iwlagn_tx_power_dbm_cmd tx_power_cmd; u8 tx_ant_cfg_cmd; - if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status), + if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status), "TX Power requested while scanning!\n")) return -EAGAIN; @@ -77,17 +76,19 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; - if (IWL_UCODE_API(priv->ucode_ver) == 1) + if (IWL_UCODE_API(priv->fw->ucode_ver) == 1) tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; else tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD; - return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC, + return iwl_dvm_send_cmd_pdu(priv, tx_ant_cfg_cmd, CMD_SYNC, sizeof(tx_power_cmd), &tx_power_cmd); } void iwlagn_temperature(struct iwl_priv *priv) { + lockdep_assert_held(&priv->statistics.lock); + /* store temperature from correct statistics (in Celsius) */ priv->temperature = le32_to_cpu(priv->statistics.common.temperature); iwl_tt_handler(priv); @@ -233,19 +234,19 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | IWL_PAN_SCD_MULTICAST_MSK; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).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", flush_cmd.fifo_control); flush_cmd.flush_control = cpu_to_le16(flush_control); - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) { - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ieee80211_stop_queues(priv->hw); if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); @@ -255,7 +256,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) iwl_trans_wait_tx_queue_empty(trans(priv)); done: ieee80211_wake_queues(priv->hw); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /* @@ -434,12 +435,12 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) if (cfg(priv)->bt_params->bt_session_2) { memcpy(&bt_cmd_2000.basic, &basic, sizeof(basic)); - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000); } else { memcpy(&bt_cmd_6000.basic, &basic, sizeof(basic)); - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000); } if (ret) @@ -452,7 +453,7 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena) struct iwl_rxon_context *ctx, *found_ctx = NULL; bool found_ap = false; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* Check whether AP or GO mode is active. */ if (rssi_ena) { @@ -565,7 +566,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) break; } - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); /* * We can not send command to firmware while scanning. When the scan @@ -574,7 +575,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) * STATUS_SCANNING to avoid race when queue_work two times from * different notifications, but quit and not perform any work at all. */ - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) + if (test_bit(STATUS_SCAN_HW, &priv->status)) goto out; iwl_update_chain_flags(priv); @@ -593,7 +594,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) */ iwlagn_bt_coex_rssi_monitor(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /* @@ -700,17 +701,16 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv, priv->kill_cts_mask = bt_kill_cts_msg[kill_msk]; /* schedule to send runtime bt_config */ - queue_work(priv->shrd->workqueue, &priv->bt_runtime_config); + queue_work(priv->workqueue, &priv->bt_runtime_config); } } int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { - unsigned long flags; struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; + struct iwl_bt_coex_profile_notif *coex = (void *)pkt->data; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { @@ -745,7 +745,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, IWL_BT_COEX_TRAFFIC_LOAD_NONE; } priv->bt_status = coex->bt_status; - queue_work(priv->shrd->workqueue, + queue_work(priv->workqueue, &priv->bt_traffic_change_work); } } @@ -754,9 +754,7 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, /* FIXME: based on notification, adjust the prio_boost */ - spin_lock_irqsave(&priv->shrd->lock, flags); priv->bt_ci_compliance = coex->bt_ci_compliance; - spin_unlock_irqrestore(&priv->shrd->lock, flags); return 0; } @@ -959,7 +957,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, struct ieee80211_key_conf *key, void *_data) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct wowlan_key_data *data = _data; struct iwl_rxon_context *ctx = data->ctx; struct aes_sc *aes_sc, *aes_tx_sc = NULL; @@ -971,7 +969,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, u16 p1k[IWLAGN_P1K_SIZE]; int ret, i; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || key->cipher == WLAN_CIPHER_SUITE_WEP104) && @@ -1077,7 +1075,7 @@ static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw, break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } int iwlagn_send_patterns(struct iwl_priv *priv, @@ -1117,13 +1115,12 @@ int iwlagn_send_patterns(struct iwl_priv *priv, } cmd.data[0] = pattern_cmd; - err = iwl_trans_send_cmd(trans(priv), &cmd); + err = iwl_dvm_send_cmd(priv, &cmd); kfree(pattern_cmd); return err; } -int iwlagn_suspend(struct iwl_priv *priv, - struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) +int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) { struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd; struct iwl_rxon_cmd rxon; @@ -1192,11 +1189,12 @@ int iwlagn_suspend(struct iwl_priv *priv, memcpy(&rxon, &ctx->active, sizeof(rxon)); + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); - priv->shrd->wowlan = true; + priv->wowlan = true; - ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_WOWLAN); + ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); if (ret) goto out; @@ -1224,11 +1222,11 @@ int iwlagn_suspend(struct iwl_priv *priv, * constraints. Since we're in the suspend path * that isn't really a problem though. */ - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); ieee80211_iter_keys(priv->hw, ctx->vif, iwlagn_wowlan_program_keys, &key_data); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (key_data.error) { ret = -EIO; goto out; @@ -1243,13 +1241,13 @@ int iwlagn_suspend(struct iwl_priv *priv, .len[0] = sizeof(*key_data.rsc_tsc), }; - ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); + ret = iwl_dvm_send_cmd(priv, &rsc_tsc_cmd); if (ret) goto out; } if (key_data.use_tkip) { - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_TKIP_PARAMS, CMD_SYNC, sizeof(tkip_cmd), &tkip_cmd); @@ -1265,7 +1263,7 @@ int iwlagn_suspend(struct iwl_priv *priv, kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN); kek_kck_cmd.replay_ctr = priv->replay_ctr; - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_KEK_KCK_MATERIAL, CMD_SYNC, sizeof(kek_kck_cmd), &kek_kck_cmd); @@ -1274,12 +1272,12 @@ int iwlagn_suspend(struct iwl_priv *priv, } } - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_D3_CONFIG, CMD_SYNC, sizeof(d3_cfg_cmd), &d3_cfg_cmd); if (ret) goto out; - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WOWLAN_WAKEUP_FILTER, CMD_SYNC, sizeof(wakeup_filter_cmd), &wakeup_filter_cmd); if (ret) @@ -1291,3 +1289,41 @@ int iwlagn_suspend(struct iwl_priv *priv, return ret; } #endif + +int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +{ + if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { + IWL_WARN(priv, "Not sending command - %s KILL\n", + iwl_is_rfkill(priv) ? "RF" : "CT"); + return -EIO; + } + + /* + * Synchronous commands from this op-mode must hold + * the mutex, this ensures we don't try to send two + * (or more) synchronous commands at a time. + */ + if (cmd->flags & CMD_SYNC) + lockdep_assert_held(&priv->mutex); + + if (priv->ucode_owner == IWL_OWNERSHIP_TM && + !(cmd->flags & CMD_ON_DEMAND)) { + IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); + return -EIO; + } + + return iwl_trans_send_cmd(trans(priv), cmd); +} + +int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, + u32 flags, u16 len, const void *data) +{ + struct iwl_host_cmd cmd = { + .id = id, + .len = { len, }, + .data = { data, }, + .flags = flags, + }; + + return iwl_dvm_send_cmd(priv, &cmd); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 334b5ae8fdd..53f8c51cfcd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 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 @@ -38,6 +38,7 @@ #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-agn.h" +#include "iwl-op-mode.h" #define RS_NAME "iwl-agn-rs" @@ -869,19 +870,16 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, { struct iwl_scale_tbl_info *tbl; bool full_concurrent = priv->bt_full_concurrent; - unsigned long flags; if (priv->bt_ant_couple_ok) { /* * Is there a need to switch between * full concurrency and 3-wire? */ - spin_lock_irqsave(&priv->shrd->lock, flags); if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) full_concurrent = true; else full_concurrent = false; - spin_unlock_irqrestore(&priv->shrd->lock, flags); } if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || (priv->bt_full_concurrent != full_concurrent)) { @@ -892,7 +890,7 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); - queue_work(priv->shrd->workqueue, &priv->bt_full_concurrency); + queue_work(priv->workqueue, &priv->bt_full_concurrency); } } @@ -909,7 +907,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, struct iwl_lq_sta *lq_sta = priv_sta; struct iwl_link_quality_cmd *table; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_priv *priv = (struct iwl_priv *)priv_r; + struct iwl_op_mode *op_mode = (struct iwl_op_mode *)priv_r; + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); enum mac80211_rate_control_flags mac_flags; u32 tx_rate; @@ -2678,7 +2677,6 @@ out: * which requires station table entry to exist). */ static void rs_initialize_lq(struct iwl_priv *priv, - struct ieee80211_conf *conf, struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta) { @@ -2737,7 +2735,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb = txrc->skb; struct ieee80211_supported_band *sband = txrc->sband; - struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; + struct iwl_op_mode *op_mode __maybe_unused = + (struct iwl_op_mode *)priv_r; + struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_lq_sta *lq_sta = priv_sta; int rate_idx; @@ -2805,9 +2805,10 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, gfp_t gfp) { struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv; - struct iwl_priv *priv; + struct iwl_op_mode *op_mode __maybe_unused = + (struct iwl_op_mode *)priv_rate; + struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode); - priv = (struct iwl_priv *)priv_rate; IWL_DEBUG_RATE(priv, "create station rate scale window\n"); return &sta_priv->lq_sta; @@ -2910,7 +2911,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->dbg_fixed_rate = 0; #endif - rs_initialize_lq(priv, conf, sta, lq_sta); + rs_initialize_lq(priv, sta, lq_sta); } static void rs_fill_link_cmd(struct iwl_priv *priv, @@ -3074,7 +3075,8 @@ static void rs_free(void *priv_rate) static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, void *priv_sta) { - struct iwl_priv *priv __maybe_unused = priv_r; + struct iwl_op_mode *op_mode __maybe_unused = priv_r; + struct iwl_priv *priv __maybe_unused = IWL_OP_MODE_GET_DVM(op_mode); IWL_DEBUG_RATE(priv, "enter\n"); IWL_DEBUG_RATE(priv, "leave\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 6675b3c816d..203b1c13c49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index b22b2976f89..44c6f712b77 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portionhelp of the ieee80211 subsystem header files. @@ -131,26 +131,27 @@ const char *get_cmd_string(u8 cmd) ******************************************************************************/ static int iwlagn_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_error_resp *err_resp = (void *)pkt->data; IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) " "seq 0x%04X ser 0x%08X\n", - le32_to_cpu(pkt->u.err_resp.error_type), - get_cmd_string(pkt->u.err_resp.cmd_id), - pkt->u.err_resp.cmd_id, - le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num), - le32_to_cpu(pkt->u.err_resp.error_info)); + le32_to_cpu(err_resp->error_type), + get_cmd_string(err_resp->cmd_id), + err_resp->cmd_id, + le16_to_cpu(err_resp->bad_cmd_seq_num), + le32_to_cpu(err_resp->error_info)); return 0; } -static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + struct iwl_csa_notification *csa = (void *)pkt->data; /* * MULTI-FIXME * See iwlagn_mac_channel_switch. @@ -158,7 +159,7 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_cmd *rxon = (void *)&ctx->active; - if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) + if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) return 0; if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { @@ -177,11 +178,11 @@ static int iwlagn_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); + struct iwl_spectrum_notification *report = (void *)pkt->data; if (!report->state) { IWL_DEBUG_11H(priv, @@ -195,12 +196,12 @@ static int iwlagn_rx_spectrum_measure_notif(struct iwl_priv *priv, } static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); + struct iwl_sleep_notification *sleep = (void *)pkt->data; IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n", sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif @@ -208,7 +209,7 @@ static int iwlagn_rx_pm_sleep_notif(struct iwl_priv *priv, } static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -217,16 +218,16 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv, IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " "notification for %s:\n", len, get_cmd_string(pkt->hdr.cmd)); - iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len); + iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len); return 0; } static int iwlagn_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw; + struct iwlagn_beacon_notif *beacon = (void *)pkt->data; #ifdef CONFIG_IWLWIFI_DEBUG u16 status = le16_to_cpu(beacon->beacon_notify_hdr.status.status); u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); @@ -266,6 +267,8 @@ static bool iwlagn_good_ack_health(struct iwl_priv *priv, if (priv->agg_tids_count) return true; + lockdep_assert_held(&priv->statistics.lock); + old = &priv->statistics.tx; actual_delta = le32_to_cpu(cur->actual_ack_cnt) - @@ -318,7 +321,7 @@ static bool iwlagn_good_plcp_health(struct iwl_priv *priv, unsigned int msecs) { int delta; - int threshold = cfg(priv)->base_params->plcp_delta_threshold; + int threshold = priv->plcp_delta_threshold; if (threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); @@ -352,7 +355,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, { unsigned int msecs; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies); @@ -487,7 +490,7 @@ iwlagn_accumulative_statistics(struct iwl_priv *priv, #endif static int iwlagn_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { unsigned long stamp = jiffies; @@ -509,9 +512,11 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n", len); + spin_lock(&priv->statistics.lock); + if (len == sizeof(struct iwl_bt_notif_statistics)) { struct iwl_bt_notif_statistics *stats; - stats = &pkt->u.stats_bt; + stats = (void *)&pkt->data; flag = &stats->flag; common = &stats->general.common; rx_non_phy = &stats->rx.general.common; @@ -529,7 +534,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, #endif } else if (len == sizeof(struct iwl_notif_statistics)) { struct iwl_notif_statistics *stats; - stats = &pkt->u.stats; + stats = (void *)&pkt->data; flag = &stats->flag; common = &stats->general.common; rx_non_phy = &stats->rx.general; @@ -542,6 +547,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n", len, sizeof(struct iwl_bt_notif_statistics), sizeof(struct iwl_notif_statistics)); + spin_unlock(&priv->statistics.lock); return 0; } @@ -569,7 +575,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, priv->rx_statistics_jiffies = stamp; - set_bit(STATUS_STATISTICS, &priv->shrd->status); + set_bit(STATUS_STATISTICS, &priv->status); /* Reschedule the statistics timer to occur in * reg_recalib_period seconds to ensure we get a @@ -578,23 +584,27 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv, mod_timer(&priv->statistics_periodic, jiffies + msecs_to_jiffies(reg_recalib_period * 1000)); - if (unlikely(!test_bit(STATUS_SCANNING, &priv->shrd->status)) && + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { iwlagn_rx_calc_noise(priv); - queue_work(priv->shrd->workqueue, &priv->run_time_calib_work); + queue_work(priv->workqueue, &priv->run_time_calib_work); } if (cfg(priv)->lib->temperature && change) cfg(priv)->lib->temperature(priv); + + spin_unlock(&priv->statistics.lock); + return 0; } static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_notif_statistics *stats = (void *)pkt->data; - if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { + if (le32_to_cpu(stats->flag) & UCODE_STATISTICS_CLEAR_MSK) { #ifdef CONFIG_IWLWIFI_DEBUGFS memset(&priv->accum_stats, 0, sizeof(priv->accum_stats)); @@ -612,12 +622,13 @@ static int iwlagn_rx_reply_statistics(struct iwl_priv *priv, /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); - unsigned long status = priv->shrd->status; + struct iwl_card_state_notif *card_state_notif = (void *)pkt->data; + u32 flags = le32_to_cpu(card_state_notif->flags); + unsigned long status = priv->status; IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n", (flags & HW_CARD_DISABLED) ? "Kill" : "On", @@ -628,16 +639,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | CT_CARD_DISABLED)) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, + iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); if (!(flags & RXON_CARD_DISABLED)) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, + iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); } if (flags & CT_CARD_DISABLED) @@ -647,32 +658,31 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, iwl_tt_exit_ct_kill(priv); if (flags & HW_CARD_DISABLED) - set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + set_bit(STATUS_RF_KILL_HW, &priv->status); else - clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + clear_bit(STATUS_RF_KILL_HW, &priv->status); if (!(flags & RXON_CARD_DISABLED)) iwl_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status))) + test_bit(STATUS_RF_KILL_HW, &priv->status))) wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)); else - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans(priv)->wait_command_queue); return 0; } static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_missed_beacon_notif *missed_beacon; + struct iwl_missed_beacon_notif *missed_beacon = (void *)pkt->data; - missed_beacon = &pkt->u.missed_beacon; if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > priv->missed_beacon_threshold) { IWL_DEBUG_CALIB(priv, @@ -681,7 +691,7 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, le32_to_cpu(missed_beacon->total_missed_becons), le32_to_cpu(missed_beacon->num_recvd_beacons), le32_to_cpu(missed_beacon->num_expected_beacons)); - if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) + if (!test_bit(STATUS_SCANNING, &priv->status)) iwl_init_sensitivity(priv); } return 0; @@ -690,13 +700,13 @@ static int iwlagn_rx_missed_beacon_notif(struct iwl_priv *priv, /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); priv->last_phy_res_valid = true; - memcpy(&priv->last_phy_res, pkt->u.raw, + memcpy(&priv->last_phy_res, pkt->data, sizeof(struct iwl_rx_phy_res)); return 0; } @@ -757,12 +767,14 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, struct ieee80211_hdr *hdr, u16 len, u32 ampdu_status, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct ieee80211_rx_status *stats) { struct sk_buff *skb; __le16 fc = hdr->frame_control; struct iwl_rxon_context *ctx; + struct page *p; + int offset; /* We only process data packets if the interface is open */ if (unlikely(!priv->is_open)) { @@ -782,7 +794,9 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, return; } - skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len); + offset = (void *)hdr - rxb_addr(rxb); + p = rxb_steal_page(rxb); + skb_add_rx_frag(skb, 0, p, offset, len); iwl_update_stats(priv, false, fc, len); @@ -793,23 +807,18 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, * sometimes even after already having transmitted frames for the * association because the new RXON may reset the information. */ - if (unlikely(ieee80211_is_beacon(fc))) { + if (unlikely(ieee80211_is_beacon(fc) && priv->passive_no_rx)) { for_each_context(priv, ctx) { - if (!ctx->last_tx_rejected) - continue; if (compare_ether_addr(hdr->addr3, ctx->active.bssid_addr)) continue; - ctx->last_tx_rejected = false; - iwl_trans_wake_any_queue(trans(priv), ctx->ctxid, - "channel got active"); + iwlagn_lift_passive_no_rx(priv); } } memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats)); ieee80211_rx(priv->hw, skb); - rxb->page = NULL; } static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) @@ -915,7 +924,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, /* Called for REPLY_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct ieee80211_hdr *header; @@ -938,12 +947,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, * received. */ if (pkt->hdr.cmd == REPLY_RX) { - phy_res = (struct iwl_rx_phy_res *)pkt->u.raw; - header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res) + phy_res = (struct iwl_rx_phy_res *)pkt->data; + header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res) + phy_res->cfg_phy_cnt); len = le16_to_cpu(phy_res->byte_count); - rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) + + rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) + phy_res->cfg_phy_cnt + len); ampdu_status = le32_to_cpu(rx_pkt_status); } else { @@ -952,10 +961,10 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, return 0; } phy_res = &priv->last_phy_res; - amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw; - header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu)); + amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; + header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); len = le16_to_cpu(amsdu->byte_count); - rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len); + rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); ampdu_status = iwlagn_translate_rx_status(priv, le32_to_cpu(rx_pkt_status)); } @@ -1035,12 +1044,12 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, } static int iwlagn_rx_noa_notification(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_wipan_noa_data *new_data, *old_data; struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw; + struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->data; /* no condition -- we're in softirq */ old_data = rcu_dereference_protected(priv->noa_data, true); @@ -1086,7 +1095,7 @@ static int iwlagn_rx_noa_notification(struct iwl_priv *priv, */ void iwl_setup_rx_handlers(struct iwl_priv *priv) { - int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, + int (**handlers)(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); handlers = priv->rx_handlers; @@ -1131,20 +1140,20 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; /* set up notification wait support */ - spin_lock_init(&priv->shrd->notif_wait_lock); - INIT_LIST_HEAD(&priv->shrd->notif_waits); - init_waitqueue_head(&priv->shrd->notif_waitq); + iwl_notification_wait_init(&priv->notif_wait); /* Set up BT Rx handlers */ - if (cfg(priv)->lib->bt_rx_handler_setup) - cfg(priv)->lib->bt_rx_handler_setup(priv); - + if (cfg(priv)->bt_params) + iwlagn_bt_rx_handler_setup(priv); } -int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, - struct iwl_device_cmd *cmd) +int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + void (*pre_rx_handler)(struct iwl_priv *, + struct iwl_rx_cmd_buffer *); int err = 0; /* @@ -1152,40 +1161,34 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, * even if the RX handler consumes the RXB we have * access to it in the notification wait entry. */ - if (!list_empty(&priv->shrd->notif_waits)) { - struct iwl_notification_wait *w; - - spin_lock(&priv->shrd->notif_wait_lock); - list_for_each_entry(w, &priv->shrd->notif_waits, list) { - if (w->cmd != pkt->hdr.cmd) - continue; + iwl_notification_wait_notify(&priv->notif_wait, pkt); + + /* RX data may be forwarded to userspace (using pre_rx_handler) in one + * of two cases: the first, that the user owns the uCode through + * testmode - in such case the pre_rx_handler is set and no further + * processing takes place. The other case is when the user want to + * monitor the rx w/o affecting the regular flow - the pre_rx_handler + * will be set but the ownership flag != IWL_OWNERSHIP_TM and the flow + * continues. + * We need to use ACCESS_ONCE to prevent a case where the handler + * changes between the check and the call. + */ + pre_rx_handler = ACCESS_ONCE(priv->pre_rx_handler); + if (pre_rx_handler) + pre_rx_handler(priv, rxb); + if (priv->ucode_owner != IWL_OWNERSHIP_TM) { + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + priv->rx_handlers_stats[pkt->hdr.cmd]++; + err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); + } else { + /* No handling needed */ IWL_DEBUG_RX(priv, - "Notif: %s, 0x%02x - wake the callers up\n", - get_cmd_string(pkt->hdr.cmd), - pkt->hdr.cmd); - w->triggered = true; - if (w->fn) - w->fn(trans(priv), pkt, w->fn_data); + "No handler needed for %s, 0x%02x\n", + get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); } - spin_unlock(&priv->shrd->notif_wait_lock); - - wake_up_all(&priv->shrd->notif_waitq); - } - - if (priv->pre_rx_handler) - priv->pre_rx_handler(priv, rxb); - - /* Based on type of command response or notification, - * handle those that need handling via function in - * rx_handlers table. See iwl_setup_rx_handlers() */ - if (priv->rx_handlers[pkt->hdr.cmd]) { - priv->rx_handlers_stats[pkt->hdr.cmd]++; - err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); - } else { - /* No handling needed */ - IWL_DEBUG_RX(priv, - "No handler needed for %s, 0x%02x\n", - get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); } return err; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 1c665941662..2e1a31797a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 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 @@ -39,7 +39,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -60,13 +60,13 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, u8 old_dev_type = send->dev_type; int ret; - iwl_init_notification_wait(priv->shrd, &disable_wait, - REPLY_WIPAN_DEACTIVATION_COMPLETE, - NULL, NULL); + iwl_init_notification_wait(&priv->notif_wait, &disable_wait, + REPLY_WIPAN_DEACTIVATION_COMPLETE, + NULL, NULL); send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; send->dev_type = RXON_DEV_TYPE_P2P; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -74,9 +74,10 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, if (ret) { IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); - iwl_remove_notification(priv->shrd, &disable_wait); + iwl_remove_notification(&priv->notif_wait, &disable_wait); } else { - ret = iwl_wait_notification(priv->shrd, &disable_wait, HZ); + ret = iwl_wait_notification(&priv->notif_wait, + &disable_wait, HZ); if (ret) IWL_ERR(priv, "Timed out waiting for PAN disable\n"); } @@ -92,7 +93,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv, int ret; send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(*send), send); send->filter_flags = old_filter; @@ -121,7 +122,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags); - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->qos_cmd, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, sizeof(struct iwl_qosparam_cmd), &ctx->qos_data.def_qos_parm); if (ret) @@ -131,7 +132,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv, static int iwlagn_update_beacon(struct iwl_priv *priv, struct ieee80211_vif *vif) { - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif); @@ -180,7 +181,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, ctx->staging.ofdm_ht_triple_stream_basic_rates; rxon_assoc.acquisition_data = ctx->staging.acquisition_data; - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_assoc_cmd, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd, CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); return ret; } @@ -266,7 +267,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, * Associated RXON doesn't clear the station table in uCode, * so we don't need to restore stations etc. after this. */ - ret = iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_cmd, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); @@ -274,8 +275,6 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, } memcpy(active, &ctx->staging, sizeof(*active)); - iwl_reprogram_ap_sta(priv, ctx); - /* IBSS beacon needs to be sent after setting assoc */ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) if (iwlagn_update_beacon(priv, ctx->vif)) @@ -315,7 +314,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; @@ -362,7 +361,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) slot0 = bcnint / 2; slot1 = bcnint - slot0; - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status) || + if (test_bit(STATUS_SCAN_HW, &priv->status) || (!ctx_bss->vif->bss_conf.idle && !ctx_bss->vif->bss_conf.assoc)) { slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME; @@ -378,7 +377,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) ctx_pan->beacon_int; slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_HW, &priv->status)) { slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME; slot1 = IWL_MIN_SLOT_TIME; } @@ -387,7 +386,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv) cmd.slots[0].width = cpu_to_le16(slot0); cmd.slots[1].width = cpu_to_le16(slot1); - ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WIPAN_PARAMS, CMD_SYNC, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); @@ -420,12 +419,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; - lockdep_assert_held(&priv->shrd->mutex); - - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - return -EINVAL; + lockdep_assert_held(&priv->mutex); - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EBUSY; /* This function hardcodes a bunch of dual-mode assumptions */ @@ -434,10 +430,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (!ctx->is_active) return 0; - /* override BSSID if necessary due to preauth */ - if (ctx->preauth_bssid) - memcpy(ctx->staging.bssid_addr, ctx->bssid, ETH_ALEN); - /* always get timestamp with Rx frame */ ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; @@ -445,8 +437,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * force CTS-to-self frames protection if RTS-CTS is not preferred * one aggregation protection method */ - if (!(cfg(priv)->ht_params && - cfg(priv)->ht_params->use_rts_for_aggregation)) + if (!hw_params(priv).use_rts_for_aggregation) ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || @@ -466,7 +457,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * receive commit_rxon request * abort any previous channel switch if still in process */ - if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status) && + if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && (priv->switch_channel != ctx->staging.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", le16_to_cpu(priv->switch_channel)); @@ -549,7 +540,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx; struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = conf->channel; @@ -558,17 +549,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) IWL_DEBUG_MAC80211(priv, "enter: changed %#x", changed); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - goto out; - - if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) { + if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); goto out; } - if (!iwl_is_ready(priv->shrd)) { + if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); goto out; } @@ -590,8 +578,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - unsigned long flags; - ch_info = iwl_get_channel_info(priv, channel->band, channel->hw_value); if (!is_channel_valid(ch_info)) { @@ -600,8 +586,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) goto out; } - spin_lock_irqsave(&priv->shrd->lock, flags); - for_each_context(priv, ctx) { /* Configure HT40 channels */ if (ctx->ht.enabled != conf_is_ht(conf)) @@ -636,8 +620,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) ctx->vif); } - spin_unlock_irqrestore(&priv->shrd->lock, flags); - iwl_update_bcast_stations(priv); /* @@ -668,7 +650,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) iwlagn_commit_rxon(priv, ctx); } out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -685,7 +667,7 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap; bool need_multiple; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -789,7 +771,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, priv->phy_calib_chain_noise_reset_cmd); - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) @@ -805,22 +787,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf, u32 changes) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); int ret; bool force = false; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (unlikely(!iwl_is_ready(priv->shrd))) { + if (unlikely(!iwl_is_ready(priv))) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return; } if (unlikely(!ctx->vif)) { IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n"); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return; } @@ -840,7 +822,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (changes & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { - priv->timestamp = bss_conf->timestamp; + priv->timestamp = bss_conf->last_tsf; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { /* @@ -851,12 +833,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, * not get stuck in this case either since it * can happen if userspace gets confused. */ - if (ctx->last_tx_rejected) { - ctx->last_tx_rejected = false; - iwl_trans_wake_any_queue(trans(priv), - ctx->ctxid, - "Disassoc: flush queue"); - } + iwlagn_lift_passive_no_rx(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; if (ctx->ctxid == IWL_RXON_CTX_BSS) @@ -900,6 +878,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, } } + /* + * If the ucode decides to do beacon filtering before + * association, it will lose beacons that are needed + * before sending frames out on passive channels. This + * causes association failures on those channels. Enable + * receiving beacons in such cases. + */ + + if (vif->type == NL80211_IFTYPE_STATION) { + if (!bss_conf->assoc) + ctx->staging.filter_flags |= RXON_FILTER_BCON_AWARE_MSK; + else + ctx->staging.filter_flags &= + ~RXON_FILTER_BCON_AWARE_MSK; + } + if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) iwlagn_commit_rxon(priv, ctx); @@ -916,7 +910,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, if (!priv->disable_chain_noise_cal) iwlagn_chain_noise_reset(priv); priv->start_calib = 1; - WARN_ON(ctx->preauth_bssid); } if (changes & BSS_CHANGED_IBSS) { @@ -934,7 +927,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, IWL_ERR(priv, "Error sending IBSS beacon\n"); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } void iwlagn_post_scan(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index e483cfa8d14..c4175603864 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -26,7 +26,7 @@ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * *****************************************************************************/ - +#include <linux/etherdevice.h> #include <net/mac80211.h> #include "iwl-dev.h" @@ -34,10 +34,14 @@ #include "iwl-agn.h" #include "iwl-trans.h" -/* priv->shrd->sta_lock must be held */ -static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) +static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) { + lockdep_assert_held(&priv->sta_lock); + if (sta_id >= IWLAGN_STATION_COUNT) { + IWL_ERR(priv, "invalid sta_id %u", sta_id); + return -EINVAL; + } if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u " "addr %pM\n", @@ -53,14 +57,15 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n", sta_id, priv->stations[sta_id].sta.sta.addr); } + return 0; } static int iwl_process_add_sta_resp(struct iwl_priv *priv, struct iwl_addsta_cmd *addsta, struct iwl_rx_packet *pkt) { + struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data; u8 sta_id = addsta->sta.sta_id; - unsigned long flags; int ret = -EIO; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { @@ -72,13 +77,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", sta_id); - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock(&priv->sta_lock); - switch (pkt->u.add_sta.status) { + switch (add_sta_resp->status) { case ADD_STA_SUCCESS_MSK: IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); - iwl_sta_ucode_activate(priv, sta_id); - ret = 0; + ret = iwl_sta_ucode_activate(priv, sta_id); break; case ADD_STA_NO_ROOM_IN_TABLE: IWL_ERR(priv, "Adding station %d failed, no room in table.\n", @@ -94,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, break; default: IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", - pkt->u.add_sta.status); + add_sta_resp->status); break; } @@ -115,12 +119,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, priv->stations[sta_id].sta.mode == STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", addsta->sta.addr); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return ret; } -int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -150,14 +154,14 @@ int iwl_send_add_sta(struct iwl_priv *priv, might_sleep(); } - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret || (flags & CMD_ASYNC)) return ret; /*else the command was successfully sent in SYNC mode, need to free * the reply page */ - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); if (cmd.handler_status) IWL_ERR(priv, "%s - error in the CMD response %d", __func__, @@ -166,34 +170,38 @@ int iwl_send_add_sta(struct iwl_priv *priv, return cmd.handler_status; } -static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, - struct ieee80211_sta *sta, - struct iwl_rxon_context *ctx) +static void iwl_sta_calc_ht_flags(struct iwl_priv *priv, + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx, + __le32 *flags, __le32 *mask) { struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; - __le32 sta_flags; u8 mimo_ps_mode; + *mask = STA_FLG_RTS_MIMO_PROT_MSK | + STA_FLG_MIMO_DIS_MSK | + STA_FLG_HT40_EN_MSK | + STA_FLG_MAX_AGG_SIZE_MSK | + STA_FLG_AGG_MPDU_DENSITY_MSK; + *flags = 0; + if (!sta || !sta_ht_inf->ht_supported) - goto done; + return; mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; - IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n", + + IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n", (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" : (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? "dynamic" : "disabled"); - sta_flags = priv->stations[index].sta.station_flags; - - sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK); - switch (mimo_ps_mode) { case WLAN_HT_CAP_SM_PS_STATIC: - sta_flags |= STA_FLG_MIMO_DIS_MSK; + *flags |= STA_FLG_MIMO_DIS_MSK; break; case WLAN_HT_CAP_SM_PS_DYNAMIC: - sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; + *flags |= STA_FLG_RTS_MIMO_PROT_MSK; break; case WLAN_HT_CAP_SM_PS_DISABLED: break; @@ -202,20 +210,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, break; } - sta_flags |= cpu_to_le32( - (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); + *flags |= cpu_to_le32( + (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); - sta_flags |= cpu_to_le32( - (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); + *flags |= cpu_to_le32( + (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) - sta_flags |= STA_FLG_HT40_EN_MSK; - else - sta_flags &= ~STA_FLG_HT40_EN_MSK; + *flags |= STA_FLG_HT40_EN_MSK; +} + +int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_sta *sta) +{ + u8 sta_id = iwl_sta_id(sta); + __le32 flags, mask; + struct iwl_addsta_cmd cmd; + + if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) + return -EINVAL; + + iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); + + spin_lock_bh(&priv->sta_lock); + priv->stations[sta_id].sta.station_flags &= ~mask; + priv->stations[sta_id].sta.station_flags |= flags; + spin_unlock_bh(&priv->sta_lock); + + memset(&cmd, 0, sizeof(cmd)); + cmd.mode = STA_CONTROL_MODIFY_MSK; + cmd.station_flags_msk = mask; + cmd.station_flags = flags; + cmd.sta.sta_id = sta_id; + + return iwl_send_add_sta(priv, &cmd, CMD_SYNC); +} - priv->stations[index].sta.station_flags = sta_flags; - done: - return; +static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx) +{ + __le32 flags, mask; + + iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask); + + lockdep_assert_held(&priv->sta_lock); + priv->stations[index].sta.station_flags &= ~mask; + priv->stations[index].sta.station_flags |= flags; } /** @@ -314,18 +355,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, struct ieee80211_sta *sta, u8 *sta_id_r) { - unsigned long flags_spin; int ret = 0; u8 sta_id; struct iwl_addsta_cmd sta_cmd; *sta_id_r = 0; - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare station %pM for addition\n", addr); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } @@ -337,7 +377,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) { IWL_DEBUG_INFO(priv, "STA %d already in process of being " "added.\n", sta_id); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EEXIST; } @@ -345,24 +385,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not " "adding again.\n", sta_id, addr); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EEXIST; } priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); /* Add station to device's station table */ ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) { - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); IWL_ERR(priv, "Adding station %pM failed.\n", priv->stations[sta_id].sta.sta.addr); priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); } *sta_id_r = sta_id; return ret; @@ -370,11 +410,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station - * - * priv->shrd->sta_lock must be held */ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) { + lockdep_assert_held(&priv->sta_lock); + /* Ucode must be active and driver must be non active */ if ((priv->stations[sta_id].used & (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != @@ -393,8 +433,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv, { struct iwl_rx_packet *pkt; int ret; - - unsigned long flags_spin; struct iwl_rem_sta_cmd rm_sta_cmd; struct iwl_host_cmd cmd = { @@ -410,12 +448,12 @@ static int iwl_send_remove_station(struct iwl_priv *priv, cmd.flags |= CMD_WANT_SKB; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) return ret; - pkt = (struct iwl_rx_packet *)cmd.reply_page; + pkt = cmd.resp_pkt; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", pkt->hdr.flags); @@ -423,14 +461,13 @@ static int iwl_send_remove_station(struct iwl_priv *priv, } if (!ret) { - switch (pkt->u.rem_sta.status) { + struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data; + switch (rem_sta_resp->status) { case REM_STA_SUCCESS_MSK: if (!temporary) { - spin_lock_irqsave(&priv->shrd->sta_lock, - flags_spin); + spin_lock_bh(&priv->sta_lock); iwl_sta_ucode_deactivate(priv, sta_id); - spin_unlock_irqrestore(&priv->shrd->sta_lock, - flags_spin); + spin_unlock_bh(&priv->sta_lock); } IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); break; @@ -440,7 +477,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, break; } } - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); return ret; } @@ -451,10 +488,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr) { - unsigned long flags; u8 tid; - if (!iwl_is_ready(priv->shrd)) { + if (!iwl_is_ready(priv)) { IWL_DEBUG_INFO(priv, "Unable to remove station %pM, device not ready.\n", addr); @@ -472,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, if (WARN_ON(sta_id == IWL_INVALID_STATION)) return -EINVAL; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", @@ -502,14 +538,49 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, if (WARN_ON(priv->num_stations < 0)) priv->num_stations = 0; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_remove_station(priv, addr, sta_id, false); out_err: - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } +void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, + const u8 *addr) +{ + u8 tid; + + if (!iwl_is_ready(priv)) { + IWL_DEBUG_INFO(priv, + "Unable to remove station %pM, device not ready.\n", + addr); + return; + } + + IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id); + + if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION)) + return; + + spin_lock_bh(&priv->sta_lock); + + WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)); + + for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) + memset(&priv->tid_data[sta_id][tid], 0, + sizeof(priv->tid_data[sta_id][tid])); + + priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; + + priv->num_stations--; + + if (WARN_ON_ONCE(priv->num_stations < 0)) + priv->num_stations = 0; + + spin_unlock_bh(&priv->sta_lock); +} + /** * iwl_clear_ucode_stations - clear ucode station table bits * @@ -522,12 +593,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { int i; - unsigned long flags_spin; bool cleared = false; IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); for (i = 0; i < IWLAGN_STATION_COUNT; i++) { if (ctx && ctx->ctxid != priv->stations[i].ctxid) continue; @@ -539,7 +609,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, cleared = true; } } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); if (!cleared) IWL_DEBUG_INFO(priv, @@ -558,20 +628,19 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { struct iwl_addsta_cmd sta_cmd; struct iwl_link_quality_cmd lq; - unsigned long flags_spin; int i; bool found = false; int ret; bool send_lq; - if (!iwl_is_ready(priv->shrd)) { + if (!iwl_is_ready(priv)) { IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); return; } IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); for (i = 0; i < IWLAGN_STATION_COUNT; i++) { if (ctx->ctxid != priv->stations[i].ctxid) continue; @@ -591,27 +660,24 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) sizeof(struct iwl_addsta_cmd)); send_lq = false; if (priv->stations[i].lq) { - if (priv->shrd->wowlan) + if (priv->wowlan) iwl_sta_fill_lq(priv, ctx, i, &lq); else memcpy(&lq, priv->stations[i].lq, sizeof(struct iwl_link_quality_cmd)); send_lq = true; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, - flags_spin); + spin_unlock_bh(&priv->sta_lock); ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); if (ret) { - spin_lock_irqsave(&priv->shrd->sta_lock, - flags_spin); + spin_lock_bh(&priv->sta_lock); IWL_ERR(priv, "Adding station %pM failed.\n", priv->stations[i].sta.sta.addr); priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&priv->shrd->sta_lock, - flags_spin); + spin_unlock_bh(&priv->sta_lock); } /* * Rate scaling has already been initialized, send @@ -620,12 +686,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) if (send_lq) iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; } } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); if (!found) IWL_DEBUG_INFO(priv, "Restoring all known stations .... " "no stations to be restored.\n"); @@ -634,52 +700,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) "complete.\n"); } -void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) -{ - unsigned long flags; - int sta_id = ctx->ap_sta_id; - int ret; - struct iwl_addsta_cmd sta_cmd; - struct iwl_link_quality_cmd lq; - bool active, have_lq = false; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); - return; - } - - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); - sta_cmd.mode = 0; - if (priv->stations[sta_id].lq) { - memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); - have_lq = true; - } - - active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; - priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); - - if (active) { - ret = iwl_send_remove_station( - priv, priv->stations[sta_id].sta.sta.addr, - sta_id, true); - if (ret) - IWL_ERR(priv, "failed to remove STA %pM (%d)\n", - priv->stations[sta_id].sta.sta.addr, ret); - } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); - - ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); - if (ret) - IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", - priv->stations[sta_id].sta.sta.addr, ret); - if (have_lq) - iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); -} - int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) { int i; @@ -693,10 +713,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv) void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { - unsigned long flags; int i; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); for (i = 0; i < IWLAGN_STATION_COUNT; i++) { if (!(priv->stations[i].used & IWL_STA_BCAST)) continue; @@ -708,7 +727,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv) kfree(priv->stations[i].lq); priv->stations[i].lq = NULL; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); } #ifdef CONFIG_IWLWIFI_DEBUG @@ -780,8 +799,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init) { int ret = 0; - unsigned long flags_spin; - struct iwl_host_cmd cmd = { .id = REPLY_TX_LINK_QUALITY_CMD, .len = { sizeof(struct iwl_link_quality_cmd), }, @@ -793,19 +810,19 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, return -EINVAL; - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); iwl_dump_lq_cmd(priv, lq); if (WARN_ON(init && (cmd.flags & CMD_ASYNC))) return -EINVAL; if (is_lq_table_valid(priv, ctx, lq)) - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); else ret = -EINVAL; @@ -816,9 +833,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, IWL_DEBUG_INFO(priv, "init LQ command complete, " "clearing sta addition status for sta %d\n", lq->sta_id); - spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin); + spin_lock_bh(&priv->sta_lock); priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin); + spin_unlock_bh(&priv->sta_lock); } return ret; } @@ -831,7 +848,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u32 rate_flags = 0; __le32 rate_n_flags; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); memset(link_cmd, 0, sizeof(*link_cmd)); @@ -903,7 +920,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, int ret; u8 sta_id; struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; if (sta_id_r) *sta_id_r = IWL_INVALID_STATION; @@ -917,9 +933,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, if (sta_id_r) *sta_id_r = sta_id; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].used |= IWL_STA_LOCAL; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); /* Set up default rate scaling table in device's station table */ link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); @@ -934,9 +950,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv, if (ret) IWL_ERR(priv, "Link quality command failed (%d)\n", ret); - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -991,7 +1007,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, cmd.len[0] = cmd_size; if (not_empty || send_if_empty) - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); else return 0; } @@ -999,7 +1015,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, int iwl_restore_default_wep_keys(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); return iwl_send_static_wepkey_cmd(priv, ctx, false); } @@ -1010,13 +1026,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", keyconf->keyidx); memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); - if (iwl_is_rfkill(priv->shrd)) { + if (iwl_is_rfkill(priv)) { IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); /* but keys in device are clear anyway so return success */ @@ -1035,7 +1051,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (keyconf->keylen != WEP_KEY_LEN_128 && keyconf->keylen != WEP_KEY_LEN_64) { @@ -1077,32 +1093,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv, struct ieee80211_sta *sta) { struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - u8 sta_id = IWL_INVALID_STATION; if (sta) - sta_id = iwl_sta_id(sta); + return iwl_sta_id(sta); /* * The device expects GTKs for station interfaces to be * installed as GTKs for the AP station. If we have no * station ID, then use the ap_sta_id in that case. */ - if (!sta && vif && vif_priv->ctx) { - switch (vif->type) { - case NL80211_IFTYPE_STATION: - sta_id = vif_priv->ctx->ap_sta_id; - break; - default: - /* - * In all other cases, the key will be - * used either for TX only or is bound - * to a station already. - */ - break; - } - } + if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx) + return vif_priv->ctx->ap_sta_id; - return sta_id; + return IWL_INVALID_STATION; } static int iwlagn_send_sta_key(struct iwl_priv *priv, @@ -1110,14 +1113,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv, u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags) { - unsigned long flags; __le16 key_flags; struct iwl_addsta_cmd sta_cmd; int i; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags |= STA_KEY_FLG_MAP_KEY_MSK; @@ -1184,7 +1186,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, struct ieee80211_sta *sta) { - unsigned long flags; struct iwl_addsta_cmd sta_cmd; u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); __le16 key_flags; @@ -1193,16 +1194,16 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, if (sta_id == IWL_INVALID_STATION) return -ENOENT; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) sta_id = IWL_INVALID_STATION; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); if (sta_id == IWL_INVALID_STATION) return 0; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); ctx->key_mapping_keys--; @@ -1242,7 +1243,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, if (sta_id == IWL_INVALID_STATION) return -EINVAL; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv); if (keyconf->hw_key_idx == WEP_INVALID_OFFSET) @@ -1297,21 +1298,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; u8 sta_id; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare broadcast station\n"); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return -EINVAL; } priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; priv->stations[sta_id].used |= IWL_STA_BCAST; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id); if (!link_cmd) { @@ -1320,9 +1320,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, return -ENOMEM; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -1336,7 +1336,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv, int iwl_update_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - unsigned long flags; struct iwl_link_quality_cmd *link_cmd; u8 sta_id = ctx->bcast_sta_id; @@ -1346,13 +1345,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv, return -ENOMEM; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); if (priv->stations[sta_id].lq) kfree(priv->stations[sta_id].lq); else IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -1376,18 +1375,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv) */ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) { - unsigned long flags; struct iwl_addsta_cmd sta_cmd; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* Remove "disable" flag, to enable Tx for this TID */ - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } @@ -1395,24 +1393,23 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid, u16 ssn) { - unsigned long flags; int sta_id; struct iwl_addsta_cmd sta_cmd; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) return -ENXIO; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].sta.station_flags_msk = 0; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } @@ -1420,11 +1417,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, int tid) { - unsigned long flags; int sta_id; struct iwl_addsta_cmd sta_cmd; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); sta_id = iwl_sta_id(sta); if (sta_id == IWL_INVALID_STATION) { @@ -1432,13 +1428,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, return -ENXIO; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); priv->stations[sta_id].sta.station_flags_msk = 0; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); } @@ -1447,16 +1443,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) { - unsigned long flags; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = - STA_MODIFY_SLEEP_TX_COUNT_MSK; - priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + struct iwl_addsta_cmd cmd = { + .mode = STA_CONTROL_MODIFY_MSK, + .station_flags = STA_FLG_PWR_SAVE_MSK, + .station_flags_msk = STA_FLG_PWR_SAVE_MSK, + .sta.sta_id = sta_id, + .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK, + .sleep_tx_count = cpu_to_le16(cnt), + }; + iwl_send_add_sta(priv, &cmd, CMD_ASYNC); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index b0dff7a753a..baaf5ba2fc3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -34,6 +34,7 @@ #include <net/mac80211.h> +#include "iwl-agn.h" #include "iwl-eeprom.h" #include "iwl-dev.h" #include "iwl-core.h" @@ -173,24 +174,24 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) struct iwl_tt_mgmt *tt = &priv->thermal_throttle; unsigned long flags; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (tt->state == IWL_TI_CT_KILL) { if (priv->thermal_throttle.ct_kill_toggle) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); priv->thermal_throttle.ct_kill_toggle = false; } else { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); priv->thermal_throttle.ct_kill_toggle = true; } - iwl_read32(bus(priv), CSR_UCODE_DRV_GP1); - spin_lock_irqsave(&bus(priv)->reg_lock, flags); - if (!iwl_grab_nic_access(bus(priv))) - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); + iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&trans(priv)->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans(priv)))) + iwl_release_nic_access(trans(priv)); + spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); /* Reschedule the ct_kill timer to occur in * CT_KILL_EXIT_DURATION seconds to ensure we get a @@ -224,7 +225,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) struct iwl_priv *priv = (struct iwl_priv *)data; struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* temperature timer expired, ready to go into CT_KILL state */ @@ -232,7 +233,7 @@ static void iwl_tt_ready_for_ct_kill(unsigned long data) 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->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); } } @@ -310,24 +311,23 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) tt->tt_power_mode = IWL_POWER_INDEX_5; break; } - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->shrd->status); + clear_bit(STATUS_CT_KILL, &priv->status); if (tt->state != IWL_TI_CT_KILL && iwl_power_update_mode(priv, true)) { /* TT state not updated * try again during next temperature read */ if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); tt->state = old_state; IWL_ERR(priv, "Cannot update power mode, " "TT state not updated\n"); } else { if (tt->state == IWL_TI_CT_KILL) { if (force) { - set_bit(STATUS_CT_KILL, - &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); } else { iwl_prepare_ct_kill_task(priv); @@ -341,7 +341,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) IWL_DEBUG_TEMP(priv, "Power Index change to %u\n", tt->tt_power_mode); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } } @@ -451,9 +451,9 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) * in case get disabled before */ iwl_set_rxon_ht(priv, &priv->current_ht_config); } - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->shrd->status); + clear_bit(STATUS_CT_KILL, &priv->status); if (tt->state != IWL_TI_CT_KILL && iwl_power_update_mode(priv, true)) { /* TT state not updated @@ -462,7 +462,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) IWL_ERR(priv, "Cannot update power mode, " "TT state not updated\n"); if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); tt->state = old_state; } else { IWL_DEBUG_TEMP(priv, @@ -473,8 +473,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) if (force) { IWL_DEBUG_TEMP(priv, "Enter IWL_TI_CT_KILL\n"); - set_bit(STATUS_CT_KILL, - &priv->shrd->status); + set_bit(STATUS_CT_KILL, &priv->status); iwl_perform_ct_kill_task(priv, true); } else { iwl_prepare_ct_kill_task(priv); @@ -486,7 +485,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) iwl_perform_ct_kill_task(priv, false); } } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } } @@ -505,10 +504,10 @@ static void iwl_bg_ct_enter(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (!iwl_is_ready(priv->shrd)) + if (!iwl_is_ready(priv)) return; if (tt->state != IWL_TI_CT_KILL) { @@ -534,10 +533,10 @@ static void iwl_bg_ct_exit(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (!iwl_is_ready(priv->shrd)) + if (!iwl_is_ready(priv)) return; /* stop ct_kill_exit_tm timer */ @@ -564,20 +563,20 @@ static void iwl_bg_ct_exit(struct work_struct *work) void iwl_tt_enter_ct_kill(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n"); - queue_work(priv->shrd->workqueue, &priv->ct_enter); + queue_work(priv->workqueue, &priv->ct_enter); } void iwl_tt_exit_ct_kill(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n"); - queue_work(priv->shrd->workqueue, &priv->ct_exit); + queue_work(priv->workqueue, &priv->ct_exit); } static void iwl_bg_tt_work(struct work_struct *work) @@ -585,7 +584,7 @@ static void iwl_bg_tt_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); s32 temp = priv->temperature; /* degrees CELSIUS except specified */ - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (!priv->thermal_throttle.advanced_tt) @@ -596,11 +595,11 @@ static void iwl_bg_tt_work(struct work_struct *work) void iwl_tt_handler(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n"); - queue_work(priv->shrd->workqueue, &priv->tt_work); + queue_work(priv->workqueue, &priv->tt_work); } /* Thermal throttling initialization diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h index 7282a23e8f1..86bbf47501c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 63bbc60be28..34adedc74d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -126,7 +126,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, u8 data_retry_limit; u8 rate_plcp; - if (priv->shrd->wowlan) { + if (priv->wowlan) { rts_retry_limit = IWLAGN_LOW_RETRY_LIMIT; data_retry_limit = IWLAGN_LOW_RETRY_LIMIT; } else { @@ -208,10 +208,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, } static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, - struct ieee80211_tx_info *info, - struct iwl_tx_cmd *tx_cmd, - struct sk_buff *skb_frag, - int sta_id) + struct ieee80211_tx_info *info, + struct iwl_tx_cmd *tx_cmd, + struct sk_buff *skb_frag) { struct ieee80211_key_conf *keyconf = info->control.hw_key; @@ -249,6 +248,35 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, } } +/** + * iwl_sta_id_or_broadcast - return sta_id or broadcast sta + * @context: the current context + * @sta: mac80211 station + * + * In certain circumstances mac80211 passes a station pointer + * that may be %NULL, for example during TX or key setup. In + * that case, we need to use the broadcast station, so this + * inline wraps that pattern. + */ +static int iwl_sta_id_or_broadcast(struct iwl_rxon_context *context, + struct ieee80211_sta *sta) +{ + int sta_id; + + if (!sta) + return context->bcast_sta_id; + + sta_id = iwl_sta_id(sta); + + /* + * mac80211 should not be passing a partially + * initialised station! + */ + WARN_ON(sta_id == IWL_INVALID_STATION); + + return sta_id; +} + /* * start REPLY_TX command process */ @@ -260,19 +288,16 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_device_cmd *dev_cmd = NULL; struct iwl_tx_cmd *tx_cmd; - __le16 fc; u8 hdr_len; u16 len, seq_number = 0; u8 sta_id, tid = IWL_MAX_TID_COUNT; - unsigned long flags; bool is_agg = false; if (info->control.vif) ctx = iwl_rxon_ctx_from_vif(info->control.vif); - spin_lock_irqsave(&priv->shrd->lock, flags); - if (iwl_is_rfkill(priv->shrd)) { + if (iwl_is_rfkill(priv)) { IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); goto drop_unlock_priv; } @@ -308,7 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) sta_id = ctx->bcast_sta_id; else { /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); + sta_id = iwl_sta_id_or_broadcast(ctx, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -322,7 +347,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) sta_priv = (void *)info->control.sta->drv_priv; if (sta_priv && sta_priv->asleep && - (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) { + (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) { /* * This sends an asynchronous command to the device, * but we can rely on it being processed before the @@ -331,6 +356,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) * counter. * For now set the counter to just 1 since we do not * support uAPSD yet. + * + * FIXME: If we get two non-bufferable frames one + * after the other, we might only send out one of + * them because this is racy. */ iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); } @@ -338,13 +367,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (info->flags & IEEE80211_TX_CTL_AMPDU) is_agg = true; - /* irqs already disabled/saved above when locking priv->shrd->lock */ - spin_lock(&priv->shrd->sta_lock); - - dev_cmd = kmem_cache_alloc(priv->tx_cmd_pool, GFP_ATOMIC); + dev_cmd = kmem_cache_alloc(iwl_tx_cmd_pool, GFP_ATOMIC); if (unlikely(!dev_cmd)) - goto drop_unlock_sta; + goto drop_unlock_priv; memset(dev_cmd, 0, sizeof(*dev_cmd)); tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; @@ -354,7 +380,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) tx_cmd->len = cpu_to_le16(len); if (info->control.hw_key) - iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); + iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb); /* TODO need this for burst mode later on */ iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); @@ -369,6 +395,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) info->driver_data[0] = ctx; info->driver_data[1] = dev_cmd; + spin_lock(&priv->sta_lock); + if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { u8 *qc = NULL; struct iwl_tid_data *tid_data; @@ -414,8 +442,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) !ieee80211_has_morefrags(fc)) priv->tid_data[sta_id][tid].seq_number = seq_number; - spin_unlock(&priv->shrd->sta_lock); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + spin_unlock(&priv->sta_lock); /* * Avoid atomic ops if it isn't an associated client. @@ -431,10 +458,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) drop_unlock_sta: if (dev_cmd) - kmem_cache_free(priv->tx_cmd_pool, dev_cmd); - spin_unlock(&priv->shrd->sta_lock); + kmem_cache_free(iwl_tx_cmd_pool, dev_cmd); + spin_unlock(&priv->sta_lock); drop_unlock_priv: - spin_unlock_irqrestore(&priv->shrd->lock, flags); return -1; } @@ -442,7 +468,6 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid) { struct iwl_tid_data *tid_data; - unsigned long flags; int sta_id; sta_id = iwl_sta_id(sta); @@ -452,7 +477,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, return -ENXIO; } - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; @@ -472,7 +497,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, IWL_WARN(priv, "Stopping AGG while state not ON " "or starting for %d on %d (%d)\n", sta_id, tid, priv->tid_data[sta_id][tid].agg.state); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -486,7 +511,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data->next_reclaimed); priv->tid_data[sta_id][tid].agg.state = IWL_EMPTYING_HW_QUEUE_DELBA; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return 0; } @@ -495,14 +520,10 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, turn_off: priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; - /* do not restore/save irqs */ - spin_unlock(&priv->shrd->sta_lock); - spin_lock(&priv->shrd->lock); + spin_unlock_bh(&priv->sta_lock); iwl_trans_tx_agg_disable(trans(priv), sta_id, tid); - spin_unlock_irqrestore(&priv->shrd->lock, flags); - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); return 0; @@ -512,7 +533,6 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn) { struct iwl_tid_data *tid_data; - unsigned long flags; int sta_id; int ret; @@ -536,7 +556,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, if (ret) return ret; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); tid_data = &priv->tid_data[sta_id][tid]; tid_data->agg.ssn = SEQ_TO_SN(tid_data->seq_number); @@ -545,7 +565,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ret = iwl_trans_tx_agg_alloc(trans(priv), sta_id, tid); if (ret) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return ret; } @@ -562,7 +582,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); return ret; } @@ -572,14 +592,13 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, { struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - unsigned long flags; u16 ssn; buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock_bh(&priv->sta_lock); ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock_bh(&priv->sta_lock); iwl_trans_tx_agg_setup(trans(priv), ctx->ctxid, sta_priv->sta_id, tid, buf_size, ssn); @@ -604,8 +623,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, sta_priv->max_agg_bufsize = min(sta_priv->max_agg_bufsize, buf_size); - if (cfg(priv)->ht_params && - cfg(priv)->ht_params->use_rts_for_aggregation) { + if (hw_params(priv).use_rts_for_aggregation) { /* * switch to RTS/CTS if it is the prefer protection * method for HT traffic @@ -635,7 +653,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) struct ieee80211_vif *vif; u8 *addr; - lockdep_assert_held(&priv->shrd->sta_lock); + lockdep_assert_held(&priv->sta_lock); addr = priv->stations[sta_id].sta.sta.addr; ctx = priv->stations[sta_id].ctxid; @@ -982,19 +1000,19 @@ static void iwl_check_abort_status(struct iwl_priv *priv, { if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) { IWL_ERR(priv, "Tx flush command to flush out all frames\n"); - if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - queue_work(priv->shrd->workqueue, &priv->tx_flush); + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + queue_work(priv->workqueue, &priv->tx_flush); } } -int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence); - struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + struct iwlagn_tx_resp *tx_resp = (void *)pkt->data; struct ieee80211_hdr *hdr; u32 status = le16_to_cpu(tx_resp->status.status); u16 ssn = iwlagn_get_scd_ssn(tx_resp); @@ -1002,7 +1020,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, int sta_id; int freed; struct ieee80211_tx_info *info; - unsigned long flags; struct sk_buff_head skbs; struct sk_buff *skb; struct iwl_rxon_context *ctx; @@ -1013,11 +1030,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> IWLAGN_TX_RES_RA_POS; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock(&priv->sta_lock); if (is_agg) iwl_rx_reply_tx_agg(priv, tx_resp); + __skb_queue_head_init(&skbs); + if (tx_resp->frame_count == 1) { u16 next_reclaimed = le16_to_cpu(tx_resp->seq_ctl); next_reclaimed = SEQ_TO_SN(next_reclaimed + 0x10); @@ -1037,8 +1056,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, next_reclaimed = ssn; } - __skb_queue_head_init(&skbs); - if (tid != IWL_TID_NON_QOS) { priv->tid_data[sta_id][tid].next_reclaimed = next_reclaimed; @@ -1047,12 +1064,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, } /*we can free until ssn % q.n_bd not inclusive */ - WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, txq_id, - ssn, status, &skbs)); + WARN_ON(iwl_trans_reclaim(trans(priv), sta_id, tid, + txq_id, ssn, &skbs)); iwlagn_check_ratid_empty(priv, sta_id, tid); freed = 0; - while (!skb_queue_empty(&skbs)) { - skb = __skb_dequeue(&skbs); + + /* process frames */ + skb_queue_walk(&skbs, skb) { hdr = (struct ieee80211_hdr *)skb->data; if (!ieee80211_is_data_qos(hdr->frame_control)) @@ -1060,7 +1078,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, info = IEEE80211_SKB_CB(skb); ctx = info->driver_data[0]; - kmem_cache_free(priv->tx_cmd_pool, + kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); memset(&info->status, 0, sizeof(info->status)); @@ -1068,9 +1086,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && iwl_is_associated_ctx(ctx) && ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) { - ctx->last_tx_rejected = true; - iwl_trans_stop_queue(trans(priv), txq_id, - "Tx on passive channel"); + /* block and stop all queues */ + priv->passive_no_rx = true; + IWL_DEBUG_TX_QUEUES(priv, "stop all queues: " + "passive channel"); + ieee80211_stop_queues(priv->hw); IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) " @@ -1094,8 +1114,6 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, if (!is_agg) iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); - ieee80211_tx_status_irqsafe(priv->hw, skb); - freed++; } @@ -1103,7 +1121,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, } iwl_check_abort_status(priv, tx_resp->frame_count, status); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); + + while (!skb_queue_empty(&skbs)) { + skb = __skb_dequeue(&skbs); + ieee80211_tx_status(priv->hw, skb); + } + return 0; } @@ -1114,17 +1138,16 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, * of frames sent via aggregation. */ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; + struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data; struct iwl_ht_agg *agg; struct sk_buff_head reclaimed_skbs; struct ieee80211_tx_info *info; struct ieee80211_hdr *hdr; struct sk_buff *skb; - unsigned long flags; int sta_id; int tid; int freed; @@ -1136,7 +1159,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); - if (scd_flow >= hw_params(priv).max_txq_num) { + if (scd_flow >= cfg(priv)->base_params->num_of_queues) { IWL_ERR(priv, "BUG_ON scd_flow is bigger than number of queues\n"); return 0; @@ -1146,12 +1169,12 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, tid = ba_resp->tid; agg = &priv->tid_data[sta_id][tid].agg; - spin_lock_irqsave(&priv->shrd->sta_lock, flags); + spin_lock(&priv->sta_lock); if (unlikely(!agg->wait_for_ba)) { if (unlikely(ba_resp->bitmap)) IWL_ERR(priv, "Received BA when not expected\n"); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + spin_unlock(&priv->sta_lock); return 0; } @@ -1161,8 +1184,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, * block-ack window (we assume that they've been successfully * transmitted ... if not, it's too late anyway). */ if (iwl_trans_reclaim(trans(priv), sta_id, tid, scd_flow, - ba_resp_scd_ssn, 0, &reclaimed_skbs)) { - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + ba_resp_scd_ssn, &reclaimed_skbs)) { + spin_unlock(&priv->sta_lock); return 0; } @@ -1198,9 +1221,8 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, iwlagn_check_ratid_empty(priv, sta_id, tid); freed = 0; - while (!skb_queue_empty(&reclaimed_skbs)) { - skb = __skb_dequeue(&reclaimed_skbs); + skb_queue_walk(&reclaimed_skbs, skb) { hdr = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(hdr->frame_control)) @@ -1209,7 +1231,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, WARN_ON_ONCE(1); info = IEEE80211_SKB_CB(skb); - kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); + kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); if (freed == 1) { /* this is the first skb we deliver in this batch */ @@ -1223,10 +1245,14 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); } + } + + spin_unlock(&priv->sta_lock); - ieee80211_tx_status_irqsafe(priv->hw, skb); + while (!skb_queue_empty(&reclaimed_skbs)) { + skb = __skb_dequeue(&reclaimed_skbs); + ieee80211_tx_status(priv->hw, skb); } - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b5c7c5f0a75..f1226dbf789 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -34,7 +34,6 @@ #include <linux/sched.h> #include <linux/skbuff.h> #include <linux/netdevice.h> -#include <linux/firmware.h> #include <linux/etherdevice.h> #include <linux/if_arp.h> @@ -43,15 +42,14 @@ #include <asm/div64.h> #include "iwl-eeprom.h" -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" #include "iwl-shared.h" -#include "iwl-bus.h" #include "iwl-trans.h" +#include "iwl-op-mode.h" /****************************************************************************** * @@ -134,7 +132,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) * beacon contents. */ - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!priv->beacon_ctx) { IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); @@ -199,7 +197,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) cmd.data[1] = priv->beacon_skb->data; cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY; - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } static void iwl_bg_beacon_update(struct work_struct *work) @@ -208,7 +206,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) container_of(work, struct iwl_priv, beacon_update); struct sk_buff *beacon; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (!priv->beacon_ctx) { IWL_ERR(priv, "updating beacon w/o beacon context!\n"); goto out; @@ -238,7 +236,7 @@ static void iwl_bg_beacon_update(struct work_struct *work) iwlagn_send_beacon_cmd(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } static void iwl_bg_bt_runtime_config(struct work_struct *work) @@ -246,11 +244,11 @@ static void iwl_bg_bt_runtime_config(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, bt_runtime_config); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* dont send host command if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; iwlagn_send_advance_bt_config(priv); } @@ -261,13 +259,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) container_of(work, struct iwl_priv, bt_full_concurrency); struct iwl_rxon_context *ctx; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) goto out; /* dont send host command if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) goto out; IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", @@ -285,7 +283,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) iwlagn_send_advance_bt_config(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /** @@ -302,11 +300,11 @@ static void iwl_bg_statistics_periodic(unsigned long data) { struct iwl_priv *priv = (struct iwl_priv *)data; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* dont send host command if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; iwl_send_statistics_request(priv, CMD_ASYNC, false); @@ -315,7 +313,7 @@ static void iwl_bg_statistics_periodic(unsigned long data) static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, u32 start_idx, u32 num_events, - u32 mode) + u32 capacity, u32 mode) { u32 i; u32 ptr; /* SRAM byte address of log data */ @@ -328,87 +326,125 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags); - if (iwl_grab_nic_access(bus(priv))) { - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); + if (unlikely(!iwl_grab_nic_access(trans(priv)))) { + spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); return; } /* Set starting address; reads will auto-increment */ - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); - rmb(); + iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); + + /* + * Refuse to read more than would have fit into the log from + * the current start_idx. This used to happen due to the race + * described below, but now WARN because the code below should + * prevent it from happening here. + */ + if (WARN_ON(num_events > capacity - start_idx)) + num_events = capacity - start_idx; /* * "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_read32(bus(priv), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (mode == 0) { - trace_iwlwifi_dev_ucode_cont_event(priv, - 0, time, ev); + trace_iwlwifi_dev_ucode_cont_event( + trans(priv)->dev, 0, time, ev); } else { - data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - trace_iwlwifi_dev_ucode_cont_event(priv, - time, data, ev); + data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + trace_iwlwifi_dev_ucode_cont_event( + trans(priv)->dev, time, data, ev); } } /* Allow device to power down */ - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + iwl_release_nic_access(trans(priv)); + spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); } static void iwl_continuous_event_trace(struct iwl_priv *priv) { u32 capacity; /* event log capacity in # entries */ + struct { + u32 capacity; + u32 mode; + u32 wrap_counter; + u32 write_counter; + } __packed read; 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 */ - base = priv->shrd->device_pointers.error_event_table; + base = priv->shrd->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - capacity = iwl_read_targ_mem(bus(priv), base); - num_wraps = iwl_read_targ_mem(bus(priv), - base + (2 * sizeof(u32))); - mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(priv), - base + (3 * sizeof(u32))); + iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read)); + + capacity = read.capacity; + mode = read.mode; + num_wraps = read.wrap_counter; + next_entry = read.write_counter; } else return; + /* + * Unfortunately, the uCode doesn't use temporary variables. + * Therefore, it can happen that we read next_entry == capacity, + * which really means next_entry == 0. + */ + if (unlikely(next_entry == capacity)) + next_entry = 0; + /* + * Additionally, the uCode increases the write pointer before + * the wraps counter, so if the write pointer is smaller than + * the old write pointer (wrap occurred) but we read that no + * wrap occurred, we actually read between the next_entry and + * num_wraps update (this does happen in practice!!) -- take + * that into account by increasing num_wraps. + */ + if (unlikely(next_entry < priv->event_log.next_entry && + num_wraps == priv->event_log.num_wraps)) + num_wraps++; + if (num_wraps == priv->event_log.num_wraps) { - iwl_print_cont_event_trace(priv, - base, priv->event_log.next_entry, - next_entry - priv->event_log.next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, priv->event_log.next_entry, + next_entry - priv->event_log.next_entry, + capacity, mode); + priv->event_log.non_wraps_count++; } else { - if ((num_wraps - priv->event_log.num_wraps) > 1) + if (num_wraps - priv->event_log.num_wraps > 1) priv->event_log.wraps_more_count++; else priv->event_log.wraps_once_count++; - trace_iwlwifi_dev_ucode_wrap_event(priv, + + trace_iwlwifi_dev_ucode_wrap_event(trans(priv)->dev, num_wraps - priv->event_log.num_wraps, next_entry, priv->event_log.next_entry); + if (next_entry < priv->event_log.next_entry) { - iwl_print_cont_event_trace(priv, base, - priv->event_log.next_entry, - capacity - priv->event_log.next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, priv->event_log.next_entry, + capacity - priv->event_log.next_entry, + capacity, mode); - iwl_print_cont_event_trace(priv, base, 0, - next_entry, mode); + iwl_print_cont_event_trace( + priv, base, 0, next_entry, capacity, mode); } else { - iwl_print_cont_event_trace(priv, base, - next_entry, capacity - next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, next_entry, + capacity - next_entry, + capacity, mode); - iwl_print_cont_event_trace(priv, base, 0, - next_entry, mode); + iwl_print_cont_event_trace( + priv, base, 0, next_entry, capacity, mode); } } + priv->event_log.num_wraps = num_wraps; priv->event_log.next_entry = next_entry; } @@ -425,7 +461,7 @@ static void iwl_bg_ucode_trace(unsigned long data) { struct iwl_priv *priv = (struct iwl_priv *)data; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (priv->event_log.ucode_trace) { @@ -441,11 +477,11 @@ static void iwl_bg_tx_flush(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, tx_flush); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* do nothing if rf-kill is on */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); @@ -475,6 +511,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); priv->contexts[IWL_RXON_CTX_BSS].interface_modes = @@ -509,620 +546,15 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); } -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); - -#define UCODE_EXPERIMENTAL_INDEX 100 -#define UCODE_EXPERIMENTAL_TAG "exp" - -static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) -{ - const char *name_pre = cfg(priv)->fw_name_pre; - char tag[8]; - - if (first) { -#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE - priv->fw_index = UCODE_EXPERIMENTAL_INDEX; - strcpy(tag, UCODE_EXPERIMENTAL_TAG); - } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { -#endif - priv->fw_index = cfg(priv)->ucode_api_max; - sprintf(tag, "%d", priv->fw_index); - } else { - priv->fw_index--; - sprintf(tag, "%d", priv->fw_index); - } - - if (priv->fw_index < cfg(priv)->ucode_api_min) { - IWL_ERR(priv, "no suitable firmware found!\n"); - return -ENOENT; - } - - sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - - IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? "EXPERIMENTAL " : "", - priv->firmware_name); - - return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - bus(priv)->dev, - GFP_KERNEL, priv, iwl_ucode_callback); -} - -struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; - size_t inst_size, data_size, init_size, init_data_size, - wowlan_inst_size, wowlan_data_size; - - u32 build; - - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; -}; - -static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces) -{ - struct iwl_ucode_header *ucode = (void *)ucode_raw->data; - u32 api_ver, hdr_size; - const u8 *src; - - priv->ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(priv->ucode_ver); - - switch (api_ver) { - default: - hdr_size = 28; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - src = ucode->u.v2.data; - break; - case 0: - case 1: - case 2: - hdr_size = 24; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = 0; - pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); - src = ucode->u.v1.data; - break; - } - - /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != hdr_size + pieces->inst_size + - pieces->data_size + pieces->init_size + - pieces->init_data_size) { - - IWL_ERR(priv, - "uCode file size %d does not match expected size\n", - (int)ucode_raw->size); - return -EINVAL; - } - - pieces->inst = src; - src += pieces->inst_size; - pieces->data = src; - src += pieces->data_size; - pieces->init = src; - src += pieces->init_size; - pieces->init_data = src; - src += pieces->init_data_size; - - return 0; -} - -static int iwlagn_load_firmware(struct iwl_priv *priv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces, - struct iwlagn_ucode_capabilities *capa) -{ - struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; - struct iwl_ucode_tlv *tlv; - size_t len = ucode_raw->size; - const u8 *data; - int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; - int tmp; - u64 alternatives; - u32 tlv_len; - enum iwl_ucode_tlv_type tlv_type; - const u8 *tlv_data; - - if (len < sizeof(*ucode)) { - IWL_ERR(priv, "uCode has invalid length: %zd\n", len); - return -EINVAL; - } - - if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { - IWL_ERR(priv, "invalid uCode magic: 0X%x\n", - le32_to_cpu(ucode->magic)); - return -EINVAL; - } - - /* - * Check which alternatives are present, and "downgrade" - * when the chosen alternative is not present, warning - * the user when that happens. Some files may not have - * any alternatives, so don't warn in that case. - */ - alternatives = le64_to_cpu(ucode->alternatives); - tmp = wanted_alternative; - if (wanted_alternative > 63) - wanted_alternative = 63; - while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) - wanted_alternative--; - if (wanted_alternative && wanted_alternative != tmp) - IWL_WARN(priv, - "uCode alternative %d not available, choosing %d\n", - tmp, wanted_alternative); - - priv->ucode_ver = le32_to_cpu(ucode->ver); - pieces->build = le32_to_cpu(ucode->build); - data = ucode->data; - - len -= sizeof(*ucode); - - while (len >= sizeof(*tlv)) { - u16 tlv_alt; - - len -= sizeof(*tlv); - tlv = (void *)data; - - tlv_len = le32_to_cpu(tlv->length); - tlv_type = le16_to_cpu(tlv->type); - tlv_alt = le16_to_cpu(tlv->alternative); - tlv_data = tlv->data; - - if (len < tlv_len) { - IWL_ERR(priv, "invalid TLV len: %zd/%u\n", - len, tlv_len); - return -EINVAL; - } - len -= ALIGN(tlv_len, 4); - data += sizeof(*tlv) + ALIGN(tlv_len, 4); - - /* - * Alternative 0 is always valid. - * - * Skip alternative TLVs that are not selected. - */ - if (tlv_alt != 0 && tlv_alt != wanted_alternative) - continue; - - switch (tlv_type) { - case IWL_UCODE_TLV_INST: - pieces->inst = tlv_data; - pieces->inst_size = tlv_len; - break; - case IWL_UCODE_TLV_DATA: - pieces->data = tlv_data; - pieces->data_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT: - pieces->init = tlv_data; - pieces->init_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT_DATA: - pieces->init_data = tlv_data; - pieces->init_data_size = tlv_len; - break; - case IWL_UCODE_TLV_BOOT: - IWL_ERR(priv, "Found unexpected BOOT ucode\n"); - break; - case IWL_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->max_probe_length = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_PAN: - if (tlv_len) - goto invalid_tlv_len; - capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; - break; - case IWL_UCODE_TLV_FLAGS: - /* must be at least one u32 */ - if (tlv_len < sizeof(u32)) - goto invalid_tlv_len; - /* and a proper number of u32s */ - if (tlv_len % sizeof(u32)) - goto invalid_tlv_len; - /* - * This driver only reads the first u32 as - * right now no more features are defined, - * if that changes then either the driver - * will not work with the new firmware, or - * it'll not take advantage of new features. - */ - capa->flags = le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_ENHANCE_SENS_TBL: - if (tlv_len) - goto invalid_tlv_len; - priv->enhance_sensitivity_table = true; - break; - case IWL_UCODE_TLV_WOWLAN_INST: - pieces->wowlan_inst = tlv_data; - pieces->wowlan_inst_size = tlv_len; - break; - case IWL_UCODE_TLV_WOWLAN_DATA: - pieces->wowlan_data = tlv_data; - pieces->wowlan_data_size = tlv_len; - break; - case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->standard_phy_calibration_size = - le32_to_cpup((__le32 *)tlv_data); - break; - default: - IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); - break; - } - } - - if (len) { - IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); - iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); - return -EINVAL; - } - - return 0; - - invalid_tlv_len: - IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); - - return -EINVAL; -} - -/** - * iwl_ucode_callback - callback when firmware was loaded - * - * If loaded successfully, copies the firmware into buffers - * for the card to fetch (via DMA). - */ -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) -{ - struct iwl_priv *priv = context; - struct iwl_ucode_header *ucode; - int err; - struct iwlagn_firmware_pieces pieces; - const unsigned int api_max = cfg(priv)->ucode_api_max; - unsigned int api_ok = cfg(priv)->ucode_api_ok; - const unsigned int api_min = cfg(priv)->ucode_api_min; - u32 api_ver; - char buildstr[25]; - u32 build; - struct iwlagn_ucode_capabilities ucode_capa = { - .max_probe_length = 200, - .standard_phy_calibration_size = - IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, - }; - - if (!api_ok) - api_ok = api_max; - - memset(&pieces, 0, sizeof(pieces)); - - if (!ucode_raw) { - if (priv->fw_index <= api_ok) - IWL_ERR(priv, - "request for firmware file '%s' failed.\n", - priv->firmware_name); - goto try_again; - } - - IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", - priv->firmware_name, ucode_raw->size); - - /* Make sure that we got at least the API version number */ - if (ucode_raw->size < 4) { - IWL_ERR(priv, "File size way too small!\n"); - goto try_again; - } - - /* Data from ucode file: header followed by uCode images */ - ucode = (struct iwl_ucode_header *)ucode_raw->data; - - if (ucode->ver) - err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); - else - err = iwlagn_load_firmware(priv, ucode_raw, &pieces, - &ucode_capa); - - if (err) - goto try_again; - - api_ver = IWL_UCODE_API(priv->ucode_ver); - build = pieces.build; - - /* - * api_ver should match the api version forming part of the - * firmware filename ... but we don't check for that and only rely - * on the API version read from firmware header from here on forward - */ - /* no api version check required for experimental uCode */ - if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, - "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - goto try_again; - } - - if (api_ver < api_ok) { - if (api_ok != api_max) - IWL_ERR(priv, "Firmware has old API version, " - "expected v%u through v%u, got v%u.\n", - api_ok, api_max, api_ver); - else - IWL_ERR(priv, "Firmware has old API version, " - "expected v%u, got v%u.\n", - api_max, api_ver); - IWL_ERR(priv, "New firmware can be obtained from " - "http://www.intellinuxwireless.org/.\n"); - } - } - - if (build) - sprintf(buildstr, " build %u%s", build, - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? " (EXP)" : ""); - else - buildstr[0] = '\0'; - - IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - snprintf(priv->hw->wiphy->fw_version, - sizeof(priv->hw->wiphy->fw_version), - "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - /* - * For any of the failures below (before allocating pci memory) - * we will try to load a version with a smaller API -- maybe the - * user just got a corrupted version of the latest API. - */ - - IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", - priv->ucode_ver); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", - pieces.inst_size); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", - pieces.data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", - pieces.init_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", - pieces.init_data_size); - - /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", - pieces.inst_size); - goto try_again; - } - - if (pieces.data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", - pieces.data_size); - goto try_again; - } - - if (pieces.init_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", - pieces.init_size); - goto try_again; - } - - if (pieces.init_data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", - pieces.init_data_size); - goto try_again; - } - - /* Allocate ucode buffers for card's bus-master loading ... */ - - /* 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(bus(priv), &trans(priv)->ucode_rt.code, - pieces.inst, pieces.inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), &trans(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(bus(priv), &trans(priv)->ucode_init.code, - pieces.init, pieces.init_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, - pieces.init_data, pieces.init_data_size)) - goto err_pci_alloc; - } - - /* WoWLAN instructions and data */ - if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(bus(priv), - &trans(priv)->ucode_wowlan.code, - pieces.wowlan_inst, - pieces.wowlan_inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), - &trans(priv)->ucode_wowlan.data, - pieces.wowlan_data, - pieces.wowlan_data_size)) - goto err_pci_alloc; - } - - /* Now that we can no longer fail, copy information */ - - /* - * The (size - 16) / 12 formula is based on the information recorded - * for each event, which is of mode 1 (including timestamp) for all - * new microcodes that include this information. - */ - priv->init_evtlog_ptr = pieces.init_evtlog_ptr; - if (pieces.init_evtlog_size) - priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; - else - priv->init_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->init_errlog_ptr = pieces.init_errlog_ptr; - priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; - if (pieces.inst_evtlog_size) - priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; - else - priv->inst_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->inst_errlog_ptr = pieces.inst_errlog_ptr; -#ifndef CONFIG_IWLWIFI_P2P - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; -#endif - - priv->new_scan_threshold_behaviour = - !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - - if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; - - /* - * if not PAN, then don't support P2P -- might be a uCode - * packaging bug or due to the eeprom check above - */ - if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; - - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { - priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; - priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - } else { - priv->sta_key_max_num = STA_KEY_MAX_NUM; - priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - } - /* - * figure out the offset of chain noise reset and gain commands - * base on the size of standard phy calibration commands table size - */ - if (ucode_capa.standard_phy_calibration_size > - IWL_MAX_PHY_CALIBRATE_TBL_SIZE) - ucode_capa.standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - - priv->phy_calib_chain_noise_reset_cmd = - ucode_capa.standard_phy_calibration_size; - priv->phy_calib_chain_noise_gain_cmd = - ucode_capa.standard_phy_calibration_size + 1; - - /* initialize all valid contexts */ - iwl_init_context(priv, ucode_capa.flags); - - /************************************************** - * This is still part of probe() in a sense... - * - * 9. Setup and register with mac80211 and debugfs - **************************************************/ - err = iwlagn_mac_setup_register(priv, &ucode_capa); - if (err) - goto out_unbind; - - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - complete(&priv->firmware_loading_complete); - return; - - try_again: - /* try next, if any */ - if (iwl_request_firmware(priv, false)) - goto out_unbind; - release_firmware(ucode_raw); - return; - - err_pci_alloc: - IWL_ERR(priv, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(trans(priv)); - out_unbind: - complete(&priv->firmware_loading_complete); - device_release_driver(bus(priv)->dev); - release_firmware(ucode_raw); -} - static void iwl_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; struct iwl_ct_kill_throttling_config adv_cmd; - unsigned long flags; int ret = 0; - spin_lock_irqsave(&priv->shrd->lock, flags); - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - spin_unlock_irqrestore(&priv->shrd->lock, flags); + priv->thermal_throttle.ct_kill_toggle = false; if (cfg(priv)->base_params->support_ct_kill_exit) { @@ -1131,7 +563,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) adv_cmd.critical_temperature_exit = cpu_to_le32(hw_params(priv).ct_kill_exit_threshold); - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, CMD_SYNC, sizeof(adv_cmd), &adv_cmd); if (ret) @@ -1146,7 +578,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) cmd.critical_temperature_R = cpu_to_le32(hw_params(priv).ct_kill_threshold); - ret = iwl_trans_send_cmd_pdu(trans(priv), + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) @@ -1172,7 +604,7 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_RT_CFG_ALL; calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } @@ -1182,9 +614,9 @@ static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) .valid = cpu_to_le32(valid_tx_ant), }; - if (IWL_UCODE_API(priv->ucode_ver) > 1) { + if (IWL_UCODE_API(priv->fw->ucode_ver) > 1) { IWL_DEBUG_HC(priv, "select valid tx ant: %u\n", valid_tx_ant); - return iwl_trans_send_cmd_pdu(trans(priv), + return iwl_dvm_send_cmd_pdu(priv, TX_ANT_CONFIGURATION_CMD, CMD_SYNC, sizeof(struct iwl_tx_ant_config_cmd), @@ -1205,20 +637,22 @@ int iwl_alive_start(struct iwl_priv *priv) int ret = 0; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - /*TODO: this should go to the transport layer */ - iwl_reset_ict(trans(priv)); - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); /* After the ALIVE response, we can send host commands to the uCode */ - set_bit(STATUS_ALIVE, &priv->shrd->status); + set_bit(STATUS_ALIVE, &priv->status); /* Enable watchdog to monitor the driver tx queues */ iwl_setup_watchdog(priv); - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) return -ERFKILL; + if (priv->event_log.ucode_trace) { + /* start collecting data now */ + mod_timer(&priv->ucode_trace, jiffies); + } + /* download priority table before any calibration request */ if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) { @@ -1235,14 +669,14 @@ int iwl_alive_start(struct iwl_priv *priv) priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; priv->cur_rssi_ctx = NULL; - iwl_send_prio_tbl(trans(priv)); + iwl_send_prio_tbl(priv); /* FIXME: w/a to force change uCode BT state machine */ - ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_OPEN, + ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; - ret = iwl_send_bt_env(trans(priv), IWL_BT_COEX_ENV_CLOSE, + ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; @@ -1263,9 +697,9 @@ int iwl_alive_start(struct iwl_priv *priv) priv->active_rate = IWL_RATES_MASK; /* Configure Tx antenna selection based on H/W config */ - iwlagn_send_tx_ant_config(priv, cfg(priv)->valid_tx_ant); + iwlagn_send_tx_ant_config(priv, hw_params(priv).valid_tx_ant); - if (iwl_is_associated_ctx(ctx) && !priv->shrd->wowlan) { + if (iwl_is_associated_ctx(ctx) && !priv->wowlan) { struct iwl_rxon_cmd *active_rxon = (struct iwl_rxon_cmd *)&ctx->active; /* apply any changes in staging */ @@ -1280,12 +714,12 @@ int iwl_alive_start(struct iwl_priv *priv) iwlagn_set_rxon_chain(priv, ctx); } - if (!priv->shrd->wowlan) { + if (!priv->wowlan) { /* WoWLAN ucode will not reply in the same way, skip it */ iwl_reset_run_time_calib(priv); } - set_bit(STATUS_READY, &priv->shrd->status); + set_bit(STATUS_READY, &priv->status); /* Configure the adapter for unassociated operation */ ret = iwlagn_commit_rxon(priv, ctx); @@ -1300,14 +734,48 @@ int iwl_alive_start(struct iwl_priv *priv) return iwl_power_update_mode(priv, true); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv); +/** + * iwl_clear_driver_stations - clear knowledge of all stations from driver + * @priv: iwl priv struct + * + * This is called during iwl_down() to make sure that in the case + * we're coming there from a hardware restart mac80211 will be + * able to reconfigure stations -- if we're getting there in the + * normal down flow then the stations will already be cleared. + */ +static void iwl_clear_driver_stations(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + + spin_lock_bh(&priv->sta_lock); + memset(priv->stations, 0, sizeof(priv->stations)); + priv->num_stations = 0; -void __iwl_down(struct iwl_priv *priv) + priv->ucode_key_table = 0; + + for_each_context(priv, ctx) { + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); + ctx->key_mapping_keys = 0; + } + + spin_unlock_bh(&priv->sta_lock); +} + +void iwl_down(struct iwl_priv *priv) { int exit_pending; IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); + lockdep_assert_held(&priv->mutex); + iwl_scan_cancel_timeout(priv, 200); /* @@ -1318,7 +786,7 @@ void __iwl_down(struct iwl_priv *priv) ieee80211_remain_on_channel_expired(priv->hw); exit_pending = - test_and_set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set * to prevent rearm timer */ @@ -1343,37 +811,29 @@ void __iwl_down(struct iwl_priv *priv) /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ if (!exit_pending) - clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + clear_bit(STATUS_EXIT_PENDING, &priv->status); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); /* Clear out all status bits but a few that are stable across reset */ - priv->shrd->status &= - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status) << + priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | - test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) << + test_bit(STATUS_GEO_CONFIGURED, &priv->status) << STATUS_GEO_CONFIGURED | - test_bit(STATUS_FW_ERROR, &priv->shrd->status) << - STATUS_FW_ERROR | - test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) << + test_bit(STATUS_EXIT_PENDING, &priv->status) << STATUS_EXIT_PENDING; + priv->shrd->status &= + test_bit(STATUS_FW_ERROR, &priv->shrd->status) << + STATUS_FW_ERROR; dev_kfree_skb(priv->beacon_skb); priv->beacon_skb = NULL; } -void iwl_down(struct iwl_priv *priv) -{ - mutex_lock(&priv->shrd->mutex); - __iwl_down(priv); - mutex_unlock(&priv->shrd->mutex); - - iwl_cancel_deferred_work(priv); -} - /***************************************************************************** * * Workqueue callbacks @@ -1385,11 +845,11 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, run_time_calib_work); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || - test_bit(STATUS_SCANNING, &priv->shrd->status)) { - mutex_unlock(&priv->shrd->mutex); + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) { + mutex_unlock(&priv->mutex); return; } @@ -1398,7 +858,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) iwl_sensitivity_calibration(priv); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } void iwlagn_prepare_restart(struct iwl_priv *priv) @@ -1410,7 +870,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) u8 bt_status; bool bt_is_sco; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); for_each_context(priv, ctx) ctx->vif = NULL; @@ -1431,7 +891,7 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) bt_status = priv->bt_status; bt_is_sco = priv->bt_is_sco; - __iwl_down(priv); + iwl_down(priv); priv->bt_full_concurrent = bt_full_concurrent; priv->bt_ci_compliance = bt_ci_compliance; @@ -1444,13 +904,13 @@ static void iwl_bg_restart(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->shrd->status)) { - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwlagn_prepare_restart(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); iwl_cancel_deferred_work(priv); ieee80211_restart_hw(priv->hw); } else { @@ -1465,7 +925,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv) { struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (!priv->hw_roc_setup) return; @@ -1488,9 +948,9 @@ static void iwlagn_disable_roc_work(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, hw_roc_disable_work.work); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwlagn_disable_roc(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } /***************************************************************************** @@ -1501,9 +961,7 @@ static void iwlagn_disable_roc_work(struct work_struct *work) static void iwl_setup_deferred_work(struct iwl_priv *priv) { - priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME); - - init_waitqueue_head(&priv->shrd->wait_command_queue); + priv->workqueue = create_singlethread_workqueue(DRV_NAME); INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); @@ -1516,8 +974,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) iwl_setup_scan_deferred_work(priv); - if (cfg(priv)->lib->bt_setup_deferred_work) - cfg(priv)->lib->bt_setup_deferred_work(priv); + if (cfg(priv)->bt_params) + iwlagn_bt_setup_deferred_work(priv); init_timer(&priv->statistics_periodic); priv->statistics_periodic.data = (unsigned long)priv; @@ -1532,10 +990,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) priv->watchdog.function = iwl_bg_watchdog; } -static void iwl_cancel_deferred_work(struct iwl_priv *priv) +void iwl_cancel_deferred_work(struct iwl_priv *priv) { - if (cfg(priv)->lib->cancel_deferred_work) - cfg(priv)->lib->cancel_deferred_work(priv); + if (cfg(priv)->bt_params) + iwlagn_bt_cancel_deferred_work(priv); cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); @@ -1550,8 +1008,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) del_timer_sync(&priv->ucode_trace); } -static void iwl_init_hw_rates(struct iwl_priv *priv, - struct ieee80211_rate *rates) +static void iwl_init_hw_rates(struct ieee80211_rate *rates) { int i; @@ -1575,21 +1032,26 @@ static int iwl_init_drv(struct iwl_priv *priv) { int ret; - spin_lock_init(&priv->shrd->sta_lock); + spin_lock_init(&priv->sta_lock); - mutex_init(&priv->shrd->mutex); + mutex_init(&priv->mutex); - INIT_LIST_HEAD(&trans(priv)->calib_results); + INIT_LIST_HEAD(&priv->calib_results); priv->ieee_channels = NULL; priv->ieee_rates = NULL; priv->band = IEEE80211_BAND_2GHZ; + priv->plcp_delta_threshold = + cfg(priv)->base_params->plcp_delta_threshold; + priv->iw_mode = NL80211_IFTYPE_STATION; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; priv->agg_tids_count = 0; + priv->ucode_owner = IWL_OWNERSHIP_DRIVER; + /* initialize force reset */ priv->force_reset[IWL_RF_RESET].reset_duration = IWL_DELAY_NEXT_FORCE_RF_RESET; @@ -1625,7 +1087,7 @@ static int iwl_init_drv(struct iwl_priv *priv) IWL_ERR(priv, "initializing geos failed: %d\n", ret); goto err_free_channel_map; } - iwl_init_hw_rates(priv, priv->ieee_rates); + iwl_init_hw_rates(priv->ieee_rates); return 0; @@ -1639,29 +1101,25 @@ static void iwl_uninit_drv(struct iwl_priv *priv) { iwl_free_geos(priv); iwl_free_channel_map(priv); - if (priv->tx_cmd_pool) - kmem_cache_destroy(priv->tx_cmd_pool); kfree(priv->scan_cmd); kfree(priv->beacon_cmd); kfree(rcu_dereference_raw(priv->noa_data)); + iwl_calib_free_results(priv); #ifdef CONFIG_IWLWIFI_DEBUGFS kfree(priv->wowlan_sram); #endif } - - -static u32 iwl_hw_detect(struct iwl_priv *priv) -{ - return iwl_read32(bus(priv), CSR_HW_REV); -} - /* Size of one Rx buffer in host DRAM */ #define IWL_RX_BUF_SIZE_4K (4 * 1024) #define IWL_RX_BUF_SIZE_8K (8 * 1024) -static int iwl_set_hw_params(struct iwl_priv *priv) +static void iwl_set_hw_params(struct iwl_priv *priv) { + if (cfg(priv)->ht_params) + hw_params(priv).use_rts_for_aggregation = + cfg(priv)->ht_params->use_rts_for_aggregation; + if (iwlagn_mod_params.amsdu_size_8K) hw_params(priv).rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); @@ -1670,49 +1128,46 @@ static int iwl_set_hw_params(struct iwl_priv *priv) get_order(IWL_RX_BUF_SIZE_4K); if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_ALL) - cfg(priv)->sku &= ~EEPROM_SKU_CAP_11N_ENABLE; + hw_params(priv).sku &= ~EEPROM_SKU_CAP_11N_ENABLE; hw_params(priv).num_ampdu_queues = cfg(priv)->base_params->num_of_ampdu_queues; - hw_params(priv).shadow_reg_enable = - cfg(priv)->base_params->shadow_reg_enable; - hw_params(priv).sku = cfg(priv)->sku; hw_params(priv).wd_timeout = cfg(priv)->base_params->wd_timeout; /* Device-specific setup */ - return cfg(priv)->lib->set_hw_params(priv); + cfg(priv)->lib->set_hw_params(priv); } static void iwl_debug_config(struct iwl_priv *priv) { - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " #ifdef CONFIG_IWLWIFI_DEBUG "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " #ifdef CONFIG_IWLWIFI_DEBUGFS "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " #ifdef CONFIG_IWLWIFI_DEVICE_TRACING "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P " #ifdef CONFIG_IWLWIFI_P2P "enabled\n"); #else @@ -1720,46 +1175,77 @@ static void iwl_debug_config(struct iwl_priv *priv) #endif } -int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, - struct iwl_cfg *cfg) +static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, + const struct iwl_fw *fw) { int err = 0; struct iwl_priv *priv; struct ieee80211_hw *hw; + struct iwl_op_mode *op_mode; u16 num_mac; - u32 hw_rev; + u32 ucode_flags; + struct iwl_trans_config trans_cfg; + static const u8 no_reclaim_cmds[] = { + REPLY_RX_PHY_CMD, + REPLY_RX, + REPLY_RX_MPDU_CMD, + REPLY_COMPRESSED_BA, + STATISTICS_NOTIFICATION, + REPLY_TX, + }; /************************ * 1. Allocating HW data ************************/ hw = iwl_alloc_all(); if (!hw) { - pr_err("%s: Cannot allocate network device\n", cfg->name); + pr_err("%s: Cannot allocate network device\n", + cfg(trans)->name); err = -ENOMEM; goto out; } - priv = hw->priv; - priv->shrd = &priv->_shrd; - bus->shrd = priv->shrd; - priv->shrd->bus = bus; - priv->shrd->priv = priv; + op_mode = hw->priv; + op_mode->ops = &iwl_dvm_ops; + priv = IWL_OP_MODE_GET_DVM(op_mode); + priv->shrd = trans->shrd; + priv->fw = fw; + /* TODO: remove fw from shared data later */ + priv->shrd->fw = fw; - priv->shrd->trans = trans_ops->alloc(priv->shrd); - if (priv->shrd->trans == NULL) { - err = -ENOMEM; - goto out_free_traffic_mem; + /* + * Populate the state variables that the transport layer needs + * to know about. + */ + trans_cfg.op_mode = op_mode; + trans_cfg.no_reclaim_cmds = no_reclaim_cmds; + trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); + + ucode_flags = fw->ucode_capa.flags; + +#ifndef CONFIG_IWLWIFI_P2P + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; +#endif + + if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { + priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + } else { + priv->sta_key_max_num = STA_KEY_MAX_NUM; + trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; } + /* Configure transport layer */ + iwl_trans_configure(trans(priv), &trans_cfg); + /* At this point both hw and priv are allocated. */ - SET_IEEE80211_DEV(hw, bus(priv)->dev); + SET_IEEE80211_DEV(priv->hw, trans(priv)->dev); - /* what debugging capabilities we have */ + /* show what debugging capabilities we have */ iwl_debug_config(priv); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); - cfg(priv) = cfg; /* is antenna coupling more than 35dB ? */ priv->bt_ant_couple_ok = @@ -1778,47 +1264,34 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now */ - spin_lock_init(&bus(priv)->reg_lock); - spin_lock_init(&priv->shrd->lock); - - /* - * stop and reset the on-board processor just in case it is in a - * strange state ... like being left stranded by a primary kernel - * and this is now the kdump kernel trying to start up - */ - iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + spin_lock_init(&trans(priv)->reg_lock); + spin_lock_init(&priv->statistics.lock); /*********************** - * 3. Read REV register + * 2. Read REV register ***********************/ - hw_rev = iwl_hw_detect(priv); IWL_INFO(priv, "Detected %s, REV=0x%X\n", - cfg(priv)->name, hw_rev); + cfg(priv)->name, trans(priv)->hw_rev); - err = iwl_trans_request_irq(trans(priv)); + err = iwl_trans_start_hw(trans(priv)); if (err) - goto out_free_trans; - - if (iwl_trans_prepare_card_hw(trans(priv))) { - err = -EIO; - IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_free_trans; - } + goto out_free_traffic_mem; /***************** - * 4. Read EEPROM + * 3. Read EEPROM *****************/ - /* Read the EEPROM */ - err = iwl_eeprom_init(priv, hw_rev); + err = iwl_eeprom_init(trans(priv), trans(priv)->hw_rev); + /* Reset chip to save power until we load uCode during "up". */ + iwl_trans_stop_hw(trans(priv)); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_free_trans; + goto out_free_traffic_mem; } err = iwl_eeprom_check_version(priv); if (err) goto out_free_eeprom; - err = iwl_eeprom_check_sku(priv); + err = iwl_eeprom_init_hw_params(priv); if (err) goto out_free_eeprom; @@ -1836,16 +1309,27 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, } /************************ - * 5. Setup HW constants + * 4. Setup HW constants ************************/ - if (iwl_set_hw_params(priv)) { - err = -ENOENT; - IWL_ERR(priv, "failed to set hw parameters\n"); - goto out_free_eeprom; + iwl_set_hw_params(priv); + + if (!(hw_params(priv).sku & EEPROM_SKU_CAP_IPAN_ENABLE)) { + IWL_DEBUG_INFO(priv, "Your EEPROM disabled PAN"); + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_PAN; + /* + * if not PAN, then don't support P2P -- might be a uCode + * packaging bug or due to the eeprom check above + */ + ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; + priv->sta_key_max_num = STA_KEY_MAX_NUM; + trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + + /* Configure transport layer again*/ + iwl_trans_configure(trans(priv), &trans_cfg); } /******************* - * 6. Setup priv + * 5. Setup priv *******************/ err = iwl_init_drv(priv); @@ -1854,92 +1338,90 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* At this point both hw and priv are initialized. */ /******************** - * 7. Setup services + * 6. Setup services ********************/ iwl_setup_deferred_work(priv); iwl_setup_rx_handlers(priv); iwl_testmode_init(priv); - /********************************************* - * 8. Enable interrupts - *********************************************/ - - iwl_enable_rfkill_int(priv); + iwl_power_initialize(priv); + iwl_tt_initialize(priv); - /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(bus(priv), - CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); - else - set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); + snprintf(priv->hw->wiphy->fw_version, + sizeof(priv->hw->wiphy->fw_version), + "%s", fw->fw_version); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); + priv->new_scan_threshold_behaviour = + !!(ucode_flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - iwl_power_initialize(priv); - iwl_tt_initialize(priv); + priv->phy_calib_chain_noise_reset_cmd = + fw->ucode_capa.standard_phy_calibration_size; + priv->phy_calib_chain_noise_gain_cmd = + fw->ucode_capa.standard_phy_calibration_size + 1; - init_completion(&priv->firmware_loading_complete); + /* initialize all valid contexts */ + iwl_init_context(priv, ucode_flags); - err = iwl_request_firmware(priv, true); + /************************************************** + * This is still part of probe() in a sense... + * + * 7. Setup and register with mac80211 and debugfs + **************************************************/ + err = iwlagn_mac_setup_register(priv, &fw->ucode_capa); if (err) goto out_destroy_workqueue; - return 0; + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, + "failed to create debugfs files. Ignoring error: %d\n", + err); + + return op_mode; out_destroy_workqueue: - destroy_workqueue(priv->shrd->workqueue); - priv->shrd->workqueue = NULL; + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; iwl_uninit_drv(priv); out_free_eeprom: iwl_eeprom_free(priv->shrd); -out_free_trans: - iwl_trans_free(trans(priv)); out_free_traffic_mem: iwl_free_traffic_mem(priv); ieee80211_free_hw(priv->hw); out: - return err; + op_mode = NULL; + return op_mode; } -void __devexit iwl_remove(struct iwl_priv * priv) +static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) { - wait_for_completion(&priv->firmware_loading_complete); + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); iwl_dbgfs_unregister(priv); - /* ieee80211_unregister_hw call wil cause iwlagn_mac_stop to - * to be called and iwl_down since we are removing the device - * we need to set STATUS_EXIT_PENDING bit. - */ - set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); - iwl_testmode_cleanup(priv); iwlagn_mac_unregister(priv); iwl_tt_exit(priv); /*This will stop the queues, move the device to low power state */ + priv->ucode_loaded = false; iwl_trans_stop_device(trans(priv)); - iwl_dealloc_ucode(trans(priv)); - iwl_eeprom_free(priv->shrd); /*netif_stop_queue(dev); */ - flush_workqueue(priv->shrd->workqueue); + flush_workqueue(priv->workqueue); /* ieee80211_unregister_hw calls iwlagn_mac_stop, which flushes - * priv->shrd->workqueue... so we can't take down the workqueue + * priv->workqueue... so we can't take down the workqueue * until now... */ - destroy_workqueue(priv->shrd->workqueue); - priv->shrd->workqueue = NULL; + destroy_workqueue(priv->workqueue); + priv->workqueue = NULL; iwl_free_traffic_mem(priv); - iwl_trans_free(trans(priv)); - iwl_uninit_drv(priv); dev_kfree_skb(priv->beacon_skb); @@ -1947,12 +1429,81 @@ void __devexit iwl_remove(struct iwl_priv * priv) ieee80211_free_hw(priv->hw); } +static void iwl_cmd_queue_full(struct iwl_op_mode *op_mode) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + if (!iwl_check_for_ct_kill(priv)) { + IWL_ERR(priv, "Restarting adapter queue is full\n"); + iwl_nic_error(op_mode); + } +} + +static void iwl_nic_config(struct iwl_op_mode *op_mode) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + cfg(priv)->lib->nic_config(priv); +} + +static void iwl_stop_sw_queue(struct iwl_op_mode *op_mode, u8 ac) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + set_bit(ac, &priv->transport_queue_stop); + ieee80211_stop_queue(priv->hw, ac); +} + +static void iwl_wake_sw_queue(struct iwl_op_mode *op_mode, u8 ac) +{ + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + clear_bit(ac, &priv->transport_queue_stop); + + if (!priv->passive_no_rx) + ieee80211_wake_queue(priv->hw, ac); +} + +void iwlagn_lift_passive_no_rx(struct iwl_priv *priv) +{ + int ac; + + if (!priv->passive_no_rx) + return; + + for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) { + if (!test_bit(ac, &priv->transport_queue_stop)) { + IWL_DEBUG_TX_QUEUES(priv, "Wake queue %d"); + ieee80211_wake_queue(priv->hw, ac); + } else { + IWL_DEBUG_TX_QUEUES(priv, "Don't wake queue %d"); + } + } + + priv->passive_no_rx = false; +} + +const struct iwl_op_mode_ops iwl_dvm_ops = { + .start = iwl_op_mode_dvm_start, + .stop = iwl_op_mode_dvm_stop, + .rx = iwl_rx_dispatch, + .queue_full = iwl_stop_sw_queue, + .queue_not_full = iwl_wake_sw_queue, + .hw_rf_kill = iwl_set_hw_rfkill_state, + .free_skb = iwl_free_skb, + .nic_error = iwl_nic_error, + .cmd_queue_full = iwl_cmd_queue_full, + .nic_config = iwl_nic_config, +}; /***************************************************************************** * * driver and module entry point * *****************************************************************************/ + +struct kmem_cache *iwl_tx_cmd_pool; + static int __init iwl_init(void) { @@ -1960,20 +1511,27 @@ static int __init iwl_init(void) pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); pr_info(DRV_COPYRIGHT "\n"); + iwl_tx_cmd_pool = kmem_cache_create("iwl_dev_cmd", + sizeof(struct iwl_device_cmd), + sizeof(void *), 0, NULL); + if (!iwl_tx_cmd_pool) + return -ENOMEM; + ret = iwlagn_rate_control_register(); if (ret) { pr_err("Unable to register rate control algorithm: %d\n", ret); - return ret; + goto error_rc_register; } ret = iwl_pci_register_driver(); - if (ret) - goto error_register; + goto error_pci_register; return ret; -error_register: +error_pci_register: iwlagn_rate_control_unregister(); +error_rc_register: + kmem_cache_destroy(iwl_tx_cmd_pool); return ret; } @@ -1981,6 +1539,7 @@ static void __exit iwl_exit(void) { iwl_pci_unregister_driver(); iwlagn_rate_control_unregister(); + kmem_cache_destroy(iwl_tx_cmd_pool); } module_exit(iwl_exit); @@ -1994,8 +1553,6 @@ MODULE_PARM_DESC(debug, "debug output mask"); module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); -module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); -MODULE_PARM_DESC(queues_num, "number of hw queues."); module_param_named(11n_disable, iwlagn_mod_params.disable_11n, uint, S_IRUGO); MODULE_PARM_DESC(11n_disable, "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); @@ -2054,7 +1611,7 @@ 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)"); + "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)"); module_param_named(power_save, iwlagn_mod_params.power_save, bool, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index f84fb3c5356..3780a03f271 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,16 +65,10 @@ #include "iwl-dev.h" -struct iwlagn_ucode_capabilities { - u32 max_probe_length; - u32 standard_phy_calibration_size; - u32 flags; -}; +struct iwl_ucode_capabilities; extern struct ieee80211_ops iwlagn_hw_ops; -int iwl_reset_ict(struct iwl_trans *trans); - static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) { hdr->op_code = cmd; @@ -83,16 +77,31 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) hdr->data_valid = 1; } -void __iwl_down(struct iwl_priv *priv); void iwl_down(struct iwl_priv *priv); +void iwl_cancel_deferred_work(struct iwl_priv *priv); void iwlagn_prepare_restart(struct iwl_priv *priv); +void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb); +int __must_check iwl_rx_dispatch(struct iwl_op_mode *op_mode, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); +void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state); +void iwl_nic_error(struct iwl_op_mode *op_mode); + +bool iwl_check_for_ct_kill(struct iwl_priv *priv); + +void iwlagn_lift_passive_no_rx(struct iwl_priv *priv); /* MAC80211 */ struct ieee80211_hw *iwl_alloc_all(void); int iwlagn_mac_setup_register(struct iwl_priv *priv, - struct iwlagn_ucode_capabilities *capa); + const struct iwl_ucode_capabilities *capa); void iwlagn_mac_unregister(struct iwl_priv *priv); +/* commands */ +int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); +int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, + u32 flags, u16 len, const void *data); + /* RXON */ int iwlagn_set_pan_params(struct iwl_priv *priv); int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); @@ -107,8 +116,18 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, /* uCode */ int iwlagn_rx_calib_result(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); +int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); +void iwl_send_prio_tbl(struct iwl_priv *priv); +int iwl_init_alive_start(struct iwl_priv *priv); +int iwl_run_init_ucode(struct iwl_priv *priv); +int iwl_load_ucode_wait_alive(struct iwl_priv *priv, + enum iwl_ucode_type ucode_type); +int iwl_send_calib_results(struct iwl_priv *priv); +int iwl_calib_set(struct iwl_priv *priv, + const struct iwl_calib_hdr *cmd, int len); +void iwl_calib_free_results(struct iwl_priv *priv); /* lib */ int iwlagn_send_tx_power(struct iwl_priv *priv); @@ -120,8 +139,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv); #ifdef CONFIG_PM_SLEEP int iwlagn_send_patterns(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); -int iwlagn_suspend(struct iwl_priv *priv, - struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); +int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan); #endif /* rx */ @@ -138,9 +156,9 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); -int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); static inline u32 iwl_tx_status_to_mac80211(u32 status) @@ -175,7 +193,7 @@ void iwlagn_disable_roc(struct iwl_priv *priv); /* bt coex */ void iwlagn_send_advance_bt_config(struct iwl_priv *priv); int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); @@ -216,6 +234,8 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct ieee80211_sta *sta, u8 *sta_id_r); int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); +void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id, + const u8 *addr); u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, const u8 *addr, bool is_ap, struct ieee80211_sta *sta); @@ -223,46 +243,12 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, u8 sta_id, struct iwl_link_quality_cmd *link_cmd); int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); -void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, +int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); +int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_sta *sta); -/** - * iwl_clear_driver_stations - clear knowledge of all stations from driver - * @priv: iwl priv struct - * - * This is called during iwl_down() to make sure that in the case - * we're coming there from a hardware restart mac80211 will be - * able to reconfigure stations -- if we're getting there in the - * normal down flow then the stations will already be cleared. - */ -static inline void iwl_clear_driver_stations(struct iwl_priv *priv) -{ - unsigned long flags; - struct iwl_rxon_context *ctx; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - memset(priv->stations, 0, sizeof(priv->stations)); - priv->num_stations = 0; - - priv->ucode_key_table = 0; - - for_each_context(priv, ctx) { - /* - * Remove all key information that is not stored as part - * of station information since mac80211 may not have had - * a chance to remove all the keys. When device is - * reconfigured by mac80211 after an error all keys will - * be reconfigured. - */ - memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); - ctx->key_mapping_keys = 0; - } - - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); -} - static inline int iwl_sta_id(struct ieee80211_sta *sta) { if (WARN_ON(!sta)) @@ -271,37 +257,6 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) return ((struct iwl_station_priv *)sta->drv_priv)->sta_id; } -/** - * iwl_sta_id_or_broadcast - return sta_id or broadcast sta - * @priv: iwl priv - * @context: the current context - * @sta: mac80211 station - * - * In certain circumstances mac80211 passes a station pointer - * that may be %NULL, for example during TX or key setup. In - * that case, we need to use the broadcast station, so this - * inline wraps that pattern. - */ -static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, - struct iwl_rxon_context *context, - struct ieee80211_sta *sta) -{ - int sta_id; - - if (!sta) - return context->bcast_sta_id; - - sta_id = iwl_sta_id(sta); - - /* - * mac80211 should not be passing a partially - * initialised station! - */ - WARN_ON(sta_id == IWL_INVALID_STATION); - - return sta_id; -} - int iwlagn_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -351,7 +306,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) } /* eeprom */ -void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv); void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac); extern int iwl_alive_start(struct iwl_priv *priv); @@ -388,4 +342,68 @@ void iwl_testmode_cleanup(struct iwl_priv *priv) } #endif +#ifdef CONFIG_IWLWIFI_DEBUG +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid); +#else +static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid) +{ +} +#endif + +/* status checks */ + +static inline int iwl_is_ready(struct iwl_priv *priv) +{ + /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are + * set but EXIT_PENDING is not */ + return test_bit(STATUS_READY, &priv->status) && + test_bit(STATUS_GEO_CONFIGURED, &priv->status) && + !test_bit(STATUS_EXIT_PENDING, &priv->status); +} + +static inline int iwl_is_alive(struct iwl_priv *priv) +{ + return test_bit(STATUS_ALIVE, &priv->status); +} + +static inline int iwl_is_rfkill(struct iwl_priv *priv) +{ + return test_bit(STATUS_RF_KILL_HW, &priv->status); +} + +static inline int iwl_is_ctkill(struct iwl_priv *priv) +{ + return test_bit(STATUS_CT_KILL, &priv->status); +} + +static inline int iwl_is_ready_rf(struct iwl_priv *priv) +{ + if (iwl_is_rfkill(priv)) + return 0; + + return iwl_is_ready(priv); +} + +#ifdef CONFIG_IWLWIFI_DEBUG +#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ +do { \ + if (!iwl_is_rfkill((m))) \ + IWL_ERR(m, fmt, ##args); \ + else \ + __iwl_err(trans(m)->dev, true, \ + !iwl_have_debug_level(IWL_DL_RADIO), \ + fmt, ##args); \ +} while (0) +#else +#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ +do { \ + if (!iwl_is_rfkill((m))) \ + IWL_ERR(m, fmt, ##args); \ + else \ + __iwl_err(trans(m)->dev, true, true, fmt, ##args); \ +} while (0) +#endif /* CONFIG_IWLWIFI_DEBUG */ + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h deleted file mode 100644 index 940d5038b39..00000000000 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ /dev/null @@ -1,209 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Intel Linux Wireless <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_bus_h__ -#define __iwl_bus_h__ - -#include <linux/types.h> -#include <linux/spinlock.h> - -/** - * DOC: Bus layer - role and goal - * - * iwl-bus.h defines the API to the bus layer of the iwlwifi driver. - * The bus layer is responsible for doing very basic bus operations that are - * listed in the iwl_bus_ops structure. - * The bus layer registers to the bus driver, advertises the supported HW and - * gets notifications about enumeration, suspend, resume. - * For the moment, the bus layer is not a linux kernel module as itself, and - * the module_init function of the driver must call the bus specific - * registration functions. These functions are listed at the end of this file. - * For the moment, there is only one implementation of this interface: PCI-e. - * This implementation is iwl-pci.c - */ - -/** - * DOC: encapsulation and type safety - * - * The iwl_bus describes the data that is shared amongst all the bus layer - * implementations. This data is visible to other layers. Data in the bus - * specific area is not visible outside the bus specific implementation. - * iwl_bus holds a pointer to iwl_shared which holds pointer to all the other - * layers of the driver (iwl_priv, iwl_trans). In fact, this is the way to go - * when the transport layer needs to call a function of another layer. - * - * In order to achieve encapsulation, iwl_priv cannot be dereferenced from the - * bus layer. Type safety is still kept since functions that gets iwl_priv gets - * a typed pointer (as opposed to void *). - */ - -/** - * DOC: probe flow - * - * The module_init calls the bus specific registration function. The - * registration to the bus layer will trigger an enumeration of the bus which - * will call the bus specific probe function. - * The first thing this function must do is to allocate the memory needed by - * iwl_bus + the bus_specific data. - * Once the bus specific probe function has configured the hardware, it - * chooses the appropriate transport layer and calls iwl_probe that will run - * the bus independent probe flow. - * - * Note: The bus specific code must set the following data in iwl_bus before it - * calls iwl_probe: - * * bus->dev - * * bus->irq - * * bus->ops - */ - -struct iwl_shared; -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 - * @get_hw_id_string: prints the hw_id in the provided buffer - * @get_hw_id: get hw_id in u32 - * @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 (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); - u32 (*get_hw_id)(struct iwl_bus *bus); - 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 - bus common data - * - * This data is common to all bus layer implementations. - * - * @dev - pointer to struct device * that represents the device - * @ops - pointer to iwl_bus_ops - * @shrd - pointer to iwl_shared which holds shared data from the upper layer - * NB: for the time being this needs to be set by the upper layer since - * it allocates the shared data - * @irq - the irq number for the device - * @reg_lock - protect hw register access - */ -struct iwl_bus { - struct device *dev; - const struct iwl_bus_ops *ops; - struct iwl_shared *shrd; - - unsigned int irq; - spinlock_t reg_lock; - - /* pointer to bus specific struct */ - /*Ensure that this pointer will always be aligned to sizeof pointer */ - char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); -}; - -static inline bool bus_get_pm_support(struct iwl_bus *bus) -{ - return bus->ops->get_pm_support(bus); -} - -static inline void bus_apm_config(struct iwl_bus *bus) -{ - bus->ops->apm_config(bus); -} - -static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], - int buf_len) -{ - bus->ops->get_hw_id_string(bus, buf, buf_len); -} - -static inline u32 bus_get_hw_id(struct iwl_bus *bus) -{ - return bus->ops->get_hw_id(bus); -} - -static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val) -{ - bus->ops->write8(bus, ofs, val); -} - -static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val) -{ - bus->ops->write32(bus, ofs, val); -} - -static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs) -{ - return bus->ops->read32(bus, ofs); -} - -/***************************************************** -* Bus layer registration functions -******************************************************/ -int __must_check iwl_pci_register_driver(void); -void iwl_pci_unregister_driver(void); - -#endif /* __iwl_bus_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index e1d78257e4a..82152311d73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,44 +68,46 @@ * This file declares the config structures for all devices. */ -extern struct iwl_cfg iwl5300_agn_cfg; -extern struct iwl_cfg iwl5100_agn_cfg; -extern struct iwl_cfg iwl5350_agn_cfg; -extern struct iwl_cfg iwl5100_bgn_cfg; -extern struct iwl_cfg iwl5100_abg_cfg; -extern struct iwl_cfg iwl5150_agn_cfg; -extern struct iwl_cfg iwl5150_abg_cfg; -extern struct iwl_cfg iwl6005_2agn_cfg; -extern struct iwl_cfg iwl6005_2abg_cfg; -extern struct iwl_cfg iwl6005_2bg_cfg; -extern struct iwl_cfg iwl6005_2agn_sff_cfg; -extern struct iwl_cfg iwl6005_2agn_d_cfg; -extern struct iwl_cfg iwl1030_bgn_cfg; -extern struct iwl_cfg iwl1030_bg_cfg; -extern struct iwl_cfg iwl6030_2agn_cfg; -extern struct iwl_cfg iwl6030_2abg_cfg; -extern struct iwl_cfg iwl6030_2bgn_cfg; -extern struct iwl_cfg iwl6030_2bg_cfg; -extern struct iwl_cfg iwl6000i_2agn_cfg; -extern struct iwl_cfg iwl6000i_2abg_cfg; -extern struct iwl_cfg iwl6000i_2bg_cfg; -extern struct iwl_cfg iwl6000_3agn_cfg; -extern struct iwl_cfg iwl6050_2agn_cfg; -extern struct iwl_cfg iwl6050_2abg_cfg; -extern struct iwl_cfg iwl6150_bgn_cfg; -extern struct iwl_cfg iwl6150_bg_cfg; -extern struct iwl_cfg iwl1000_bgn_cfg; -extern struct iwl_cfg iwl1000_bg_cfg; -extern struct iwl_cfg iwl100_bgn_cfg; -extern struct iwl_cfg iwl100_bg_cfg; -extern struct iwl_cfg iwl130_bgn_cfg; -extern struct iwl_cfg iwl130_bg_cfg; -extern struct iwl_cfg iwl2000_2bgn_cfg; -extern struct iwl_cfg iwl2000_2bgn_d_cfg; -extern struct iwl_cfg iwl2030_2bgn_cfg; -extern struct iwl_cfg iwl6035_2agn_cfg; -extern struct iwl_cfg iwl105_bgn_cfg; -extern struct iwl_cfg iwl105_bgn_d_cfg; -extern struct iwl_cfg iwl135_bgn_cfg; +extern const struct iwl_cfg iwl5300_agn_cfg; +extern const struct iwl_cfg iwl5100_agn_cfg; +extern const struct iwl_cfg iwl5350_agn_cfg; +extern const struct iwl_cfg iwl5100_bgn_cfg; +extern const struct iwl_cfg iwl5100_abg_cfg; +extern const struct iwl_cfg iwl5150_agn_cfg; +extern const struct iwl_cfg iwl5150_abg_cfg; +extern const struct iwl_cfg iwl6005_2agn_cfg; +extern const struct iwl_cfg iwl6005_2abg_cfg; +extern const struct iwl_cfg iwl6005_2bg_cfg; +extern const struct iwl_cfg iwl6005_2agn_sff_cfg; +extern const struct iwl_cfg iwl6005_2agn_d_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; +extern const struct iwl_cfg iwl1030_bgn_cfg; +extern const struct iwl_cfg iwl1030_bg_cfg; +extern const struct iwl_cfg iwl6030_2agn_cfg; +extern const struct iwl_cfg iwl6030_2abg_cfg; +extern const struct iwl_cfg iwl6030_2bgn_cfg; +extern const struct iwl_cfg iwl6030_2bg_cfg; +extern const struct iwl_cfg iwl6000i_2agn_cfg; +extern const struct iwl_cfg iwl6000i_2abg_cfg; +extern const struct iwl_cfg iwl6000i_2bg_cfg; +extern const struct iwl_cfg iwl6000_3agn_cfg; +extern const struct iwl_cfg iwl6050_2agn_cfg; +extern const struct iwl_cfg iwl6050_2abg_cfg; +extern const struct iwl_cfg iwl6150_bgn_cfg; +extern const struct iwl_cfg iwl6150_bg_cfg; +extern const struct iwl_cfg iwl1000_bgn_cfg; +extern const struct iwl_cfg iwl1000_bg_cfg; +extern const struct iwl_cfg iwl100_bgn_cfg; +extern const struct iwl_cfg iwl100_bg_cfg; +extern const struct iwl_cfg iwl130_bgn_cfg; +extern const struct iwl_cfg iwl130_bg_cfg; +extern const struct iwl_cfg iwl2000_2bgn_cfg; +extern const struct iwl_cfg iwl2000_2bgn_d_cfg; +extern const struct iwl_cfg iwl2030_2bgn_cfg; +extern const struct iwl_cfg iwl6035_2agn_cfg; +extern const struct iwl_cfg iwl105_bgn_cfg; +extern const struct iwl_cfg iwl105_bgn_d_cfg; +extern const struct iwl_cfg iwl135_bgn_cfg; #endif /* __iwl_pci_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index f822ac447c3..9ed73e5154b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,22 +69,9 @@ #ifndef __iwl_commands_h__ #define __iwl_commands_h__ -#include <linux/etherdevice.h> #include <linux/ieee80211.h> +#include <linux/types.h> -struct iwl_priv; - -/* uCode version contains 4 values: Major/Minor/API/Serial */ -#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) -#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) -#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) -#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) - - -/* Tx rates */ -#define IWL_CCK_RATES 4 -#define IWL_OFDM_RATES 8 -#define IWL_MAX_RATES (IWL_CCK_RATES + IWL_OFDM_RATES) enum { REPLY_ALIVE = 0x1, @@ -213,48 +200,6 @@ enum { /* iwl_cmd_header flags value */ #define IWL_CMD_FAILED_MSK 0x40 -#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) -#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) -#define SEQ_TO_INDEX(s) ((s) & 0xff) -#define INDEX_TO_SEQ(i) ((i) & 0xff) -#define SEQ_RX_FRAME cpu_to_le16(0x8000) - -/** - * struct iwl_cmd_header - * - * This header format appears in the beginning of each command sent from the - * driver, and each response/notification received from uCode. - */ -struct iwl_cmd_header { - u8 cmd; /* Command ID: REPLY_RXON, etc. */ - u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ - /* - * The driver sets up the sequence number to values of its choosing. - * uCode does not use this value, but passes it back to the driver - * when sending the response to each driver-originated command, so - * the driver can match the response to the command. Since the values - * don't get used by uCode, the driver may set up an arbitrary format. - * - * There is one exception: uCode sets bit 15 when it originates - * the response/notification, i.e. when the response/notification - * is not a direct response to a command sent by the driver. For - * example, uCode issues REPLY_RX when it sends a received frame - * to the driver; it is not a direct response to any driver command. - * - * The Linux driver uses the following format: - * - * 0:7 tfd index - position within TX queue - * 8:12 TX queue id - * 13:14 reserved - * 15 unsolicited RX or uCode-originated notification - */ - __le16 sequence; - - /* command or response/notification data follows immediately */ - u8 data[0]; -} __packed; - - /** * iwlagn rate_n_flags bit fields * @@ -3151,8 +3096,6 @@ struct iwl_enhance_sensitivity_cmd { */ /* Phy calibration command for series */ -/* The default calibrate table size if not specified by firmware */ -#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 enum { IWL_PHY_CALIBRATE_DC_CMD = 8, IWL_PHY_CALIBRATE_LO_CMD = 9, @@ -3161,11 +3104,8 @@ enum { IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, }; -#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) - /* This enum defines the bitmap of various calibrations to enable in both * init ucode and runtime ucode through CALIBRATION_CFG_CMD. */ @@ -3905,50 +3845,6 @@ struct iwlagn_wowlan_kek_kck_material_cmd { __le64 replay_ctr; } __packed; -/****************************************************************************** - * (13) - * Union of all expected notifications/responses: - * - *****************************************************************************/ -#define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ - -struct iwl_rx_packet { - /* - * The first 4 bytes of the RX frame header contain both the RX frame - * size and some flags. - * Bit fields: - * 31: flag flush RB request - * 30: flag ignore TC (terminal counter) request - * 29: flag fast IRQ request - * 28-14: Reserved - * 13-00: RX frame size - */ - __le32 len_n_flags; - struct iwl_cmd_header hdr; - union { - struct iwl_alive_resp alive_frame; - struct iwl_spectrum_notification spectrum_notif; - struct iwl_csa_notification csa_notif; - struct iwl_error_resp err_resp; - struct iwl_card_state_notif card_state_notif; - struct iwl_add_sta_resp add_sta; - struct iwl_rem_sta_resp rem_sta; - struct iwl_sleep_notification sleep_notif; - struct iwl_spectrum_resp spectrum; - struct iwl_notif_statistics stats; - struct iwl_bt_notif_statistics stats_bt; - struct iwl_compressed_ba_resp compressed_ba; - struct iwl_missed_beacon_notif missed_beacon; - struct iwl_coex_medium_notification coex_medium_notif; - struct iwl_coex_event_resp coex_event; - struct iwl_bt_coex_profile_notif bt_coex_profile_notif; - __le32 status; - u8 raw[0]; - } u; -} __packed; - -int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); - /* * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7bcfa781e0b..46490d3b95b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -38,7 +38,6 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-power.h" -#include "iwl-agn.h" #include "iwl-shared.h" #include "iwl-agn.h" #include "iwl-trans.h" @@ -114,7 +113,7 @@ int iwl_init_geos(struct iwl_priv *priv) if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { IWL_DEBUG_INFO(priv, "Geography modes already initialized.\n"); - set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); + set_bit(STATUS_GEO_CONFIGURED, &priv->status); return 0; } @@ -137,7 +136,7 @@ int iwl_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 (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) iwl_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_5GHZ); @@ -147,7 +146,7 @@ int iwl_init_geos(struct iwl_priv *priv) sband->bitrates = rates; sband->n_bitrates = IWL_RATE_COUNT_LEGACY; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) iwl_init_ht_hw_capab(priv, &sband->ht_cap, IEEE80211_BAND_2GHZ); @@ -202,19 +201,18 @@ int iwl_init_geos(struct iwl_priv *priv) priv->tx_power_next = max_tx_power; if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && - cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { - char buf[32]; - bus_get_hw_id_string(bus(priv), buf, sizeof(buf)); + hw_params(priv).sku & EEPROM_SKU_CAP_BAND_52GHZ) { IWL_INFO(priv, "Incorrectly detected BG card as ABG. " - "Please send your %s to maintainer.\n", buf); - cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; + "Please send your %s to maintainer.\n", + trans(priv)->hw_id_str); + hw_params(priv).sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; } IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", priv->bands[IEEE80211_BAND_2GHZ].n_channels, priv->bands[IEEE80211_BAND_5GHZ].n_channels); - set_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); + set_bit(STATUS_GEO_CONFIGURED, &priv->status); return 0; } @@ -226,7 +224,7 @@ void iwl_free_geos(struct iwl_priv *priv) { kfree(priv->ieee_channels); kfree(priv->ieee_rates); - clear_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status); + clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } static bool iwl_is_channel_extension(struct iwl_priv *priv, @@ -318,7 +316,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) conf = &priv->hw->conf; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); @@ -371,7 +369,7 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) le32_to_cpu(ctx->timing.beacon_init_val), le16_to_cpu(ctx->timing.atim_window)); - return iwl_trans_send_cmd_pdu(trans(priv), ctx->rxon_timing_cmd, + return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd, CMD_SYNC, sizeof(ctx->timing), &ctx->timing); } @@ -644,7 +642,7 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv, * NOTE: Does not commit to the hardware; it sets appropriate bit fields * in the staging RXON flag structure based on the ch->band */ -int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, +void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, struct iwl_rxon_context *ctx) { enum ieee80211_band band = ch->band; @@ -652,7 +650,7 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, if ((le16_to_cpu(ctx->staging.channel) == channel) && (priv->band == band)) - return 0; + return; ctx->staging.channel = cpu_to_le16(channel); if (band == IEEE80211_BAND_5GHZ) @@ -664,7 +662,6 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band); - return 0; } void iwl_set_flags_for_band(struct iwl_priv *priv, @@ -801,11 +798,10 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) */ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, - &priv->shrd->status)) + if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) ieee80211_chswitch_done(ctx->vif, is_success); } @@ -832,24 +828,32 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, } #endif -void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) +static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) { unsigned int reload_msec; unsigned long reload_jiffies; +#ifdef CONFIG_IWLWIFI_DEBUG + if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) + iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); +#endif + + /* uCode is no longer loaded. */ + priv->ucode_loaded = false; + /* Set the FW error flag -- cleared on iwl_down */ set_bit(STATUS_FW_ERROR, &priv->shrd->status); /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status); - iwl_abort_notification_waits(priv->shrd); + iwl_abort_notification_waits(&priv->notif_wait); /* Keep the restart process from trying to send host * commands by clearing the ready bit */ - clear_bit(STATUS_READY, &priv->shrd->status); + clear_bit(STATUS_READY, &priv->status); - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans(priv)->wait_command_queue); if (!ondemand) { /* @@ -872,140 +876,17 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) priv->reload_count = 0; } - if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { if (iwlagn_mod_params.restart_fw) { IWL_DEBUG_FW_ERRORS(priv, "Restarting adapter due to uCode error.\n"); - queue_work(priv->shrd->workqueue, &priv->restart); + queue_work(priv->workqueue, &priv->restart); } else IWL_DEBUG_FW_ERRORS(priv, "Detected FW error, but not restarting\n"); } } -static int iwl_apm_stop_master(struct iwl_priv *priv) -{ - int ret = 0; - - /* stop device's busmaster DMA activity */ - iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - - ret = iwl_poll_bit(bus(priv), CSR_RESET, - CSR_RESET_REG_FLAG_MASTER_DISABLED, - CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); - if (ret) - IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n"); - - IWL_DEBUG_INFO(priv, "stop master\n"); - - return ret; -} - -void iwl_apm_stop(struct iwl_priv *priv) -{ - IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); - - clear_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); - - /* Stop device's DMA activity */ - iwl_apm_stop_master(priv); - - /* Reset the entire device */ - iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - udelay(10); - - /* - * Clear "initialization complete" bit to move adapter from - * D0A* (powered-up Active) --> D0U* (Uninitialized) state. - */ - iwl_clear_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); -} - - -/* - * Start up NIC's basic functionality after it has been reset - * (e.g. after platform boot, or shutdown via iwl_apm_stop()) - * NOTE: This does not load uCode nor start the embedded processor - */ -int iwl_apm_init(struct iwl_priv *priv) -{ - int ret = 0; - IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); - - /* - * Use "set_bit" below rather than "write", to preserve any hardware - * bits already set by default after reset. - */ - - /* Disable L0S exit timer (platform NMI Work/Around) */ - iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); - - /* - * Disable L0s without affecting L1; - * don't wait for ICH L0s (ICH bug W/A) - */ - iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); - - /* Set FH wait threshold to maximum (HW error during stress W/A) */ - iwl_set_bit(bus(priv), CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); - - /* - * Enable HAP INTA (interrupt from management bus) to - * wake device's PCI Express link L1a -> L0s - */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - - bus_apm_config(bus(priv)); - - /* Configure analog phase-lock-loop before activating to D0A */ - if (cfg(priv)->base_params->pll_cfg_val) - iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG, - cfg(priv)->base_params->pll_cfg_val); - - /* - * Set "initialization complete" bit to move adapter from - * D0U* --> D0A* (powered-up active) state. - */ - iwl_set_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - - /* - * Wait for clock stabilization; once stabilized, access to - * device-internal resources is supported, e.g. iwl_write_prph() - * and accesses to uCode SRAM. - */ - ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); - if (ret < 0) { - IWL_DEBUG_INFO(priv, "Failed to init the card\n"); - goto out; - } - - /* - * Enable DMA clock and wait for it to stabilize. - * - * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits - * do not disable clocks. This preserves any hardware bits already - * set by default in "CLK_CTRL_REG" after reset. - */ - iwl_write_prph(bus(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); - udelay(20); - - /* Disable L1-Active */ - iwl_set_bits_prph(bus(priv), APMG_PCIDEV_STT_REG, - APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - - set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); - -out: - return ret; -} - - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; @@ -1013,7 +894,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) bool defer; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (priv->tx_power_user_lmt == tx_power && !force) return 0; @@ -1033,7 +914,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) return -EINVAL; } - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return -EIO; /* scan complete and commit_rxon use tx_power_next value, @@ -1041,7 +922,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) priv->tx_power_next = tx_power; /* do not set tx power when scanning or channel changing */ - defer = test_bit(STATUS_SCANNING, &priv->shrd->status) || + defer = test_bit(STATUS_SCANNING, &priv->status) || memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)); if (defer && !force) { IWL_DEBUG_INFO(priv, "Deferring tx power set\n"); @@ -1079,7 +960,7 @@ void iwl_send_bt_config(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "BT coex %s\n", (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); - if (iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG, + if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, CMD_SYNC, sizeof(struct iwl_bt_cmd), &bt_cmd)) IWL_ERR(priv, "failed to send BT Coex Config\n"); } @@ -1092,12 +973,12 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) }; if (flags & CMD_ASYNC) - return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, + return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, CMD_ASYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); else - return iwl_trans_send_cmd_pdu(trans(priv), REPLY_STATISTICS_CMD, + return iwl_dvm_send_cmd_pdu(priv, REPLY_STATISTICS_CMD, CMD_SYNC, sizeof(struct iwl_statistics_cmd), &statistics_cmd); @@ -1124,7 +1005,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) { u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE; - if (iwl_get_debug_level(priv->shrd) & IWL_DL_TX) { + if (iwl_have_debug_level(IWL_DL_TX)) { if (!priv->tx_traffic) { priv->tx_traffic = kzalloc(traffic_size, GFP_KERNEL); @@ -1132,7 +1013,7 @@ int iwl_alloc_traffic_mem(struct iwl_priv *priv) return -ENOMEM; } } - if (iwl_get_debug_level(priv->shrd) & IWL_DL_RX) { + if (iwl_have_debug_level(IWL_DL_RX)) { if (!priv->rx_traffic) { priv->rx_traffic = kzalloc(traffic_size, GFP_KERNEL); @@ -1159,7 +1040,7 @@ void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv, __le16 fc; u16 len; - if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_TX))) + if (likely(!iwl_have_debug_level(IWL_DL_TX))) return; if (!priv->tx_traffic) @@ -1183,7 +1064,7 @@ void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv, __le16 fc; u16 len; - if (likely(!(iwl_get_debug_level(priv->shrd) & IWL_DL_RX))) + if (likely(!iwl_have_debug_level(IWL_DL_RX))) return; if (!priv->rx_traffic) @@ -1340,7 +1221,7 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) static void iwl_force_rf_reset(struct iwl_priv *priv) { - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (!iwl_is_any_associated(priv)) { @@ -1365,7 +1246,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) { struct iwl_force_reset *force_reset; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EINVAL; if (mode >= IWL_MAX_FORCE_RESET) { @@ -1421,7 +1302,7 @@ int iwl_cmd_echo_test(struct iwl_priv *priv) .flags = CMD_SYNC, }; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) IWL_ERR(priv, "echo testing fail: 0X%x\n", ret); else @@ -1455,30 +1336,20 @@ void iwl_bg_watchdog(unsigned long data) int cnt; unsigned long timeout; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) return; - timeout = cfg(priv)->base_params->wd_timeout; + timeout = hw_params(priv).wd_timeout; if (timeout == 0) return; - /* monitor and check for stuck cmd queue */ - if (iwl_check_stuck_queue(priv, priv->shrd->cmd_queue)) - return; - - /* monitor and check for other stuck queues */ - if (iwl_is_any_associated(priv)) { - for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) { - /* skip as we already checked the command queue */ - if (cnt == priv->shrd->cmd_queue) - continue; - if (iwl_check_stuck_queue(priv, cnt)) - return; - } - } + /* monitor and check for stuck queues */ + for (cnt = 0; cnt < cfg(priv)->base_params->num_of_queues; cnt++) + if (iwl_check_stuck_queue(priv, cnt)) + return; mod_timer(&priv->watchdog, jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); @@ -1486,7 +1357,7 @@ void iwl_bg_watchdog(unsigned long data) void iwl_setup_watchdog(struct iwl_priv *priv) { - unsigned int timeout = cfg(priv)->base_params->wd_timeout; + unsigned int timeout = hw_params(priv).wd_timeout; if (!iwlagn_mod_params.wd_disable) { /* use system default */ @@ -1580,31 +1451,30 @@ __le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base, return cpu_to_le32(res); } -void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state) +void iwl_nic_error(struct iwl_op_mode *op_mode) { - wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + iwlagn_fw_error(priv, false); } -void iwl_nic_config(struct iwl_priv *priv) +void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) { - cfg(priv)->lib->nic_config(priv); + struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); + + if (state) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + + wiphy_rfkill_set_hw_state(priv->hw->wiphy, state); } -void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb) +void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) { struct ieee80211_tx_info *info; info = IEEE80211_SKB_CB(skb); - kmem_cache_free(priv->tx_cmd_pool, (info->driver_data[1])); + kmem_cache_free(iwl_tx_cmd_pool, (info->driver_data[1])); dev_kfree_skb_any(skb); } - -void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac) -{ - ieee80211_stop_queue(priv->hw, ac); -} - -void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac) -{ - ieee80211_wake_queue(priv->hw, ac); -} diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7bf76ab94dd..635eb685ede 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,13 +76,7 @@ struct iwl_cmd; struct iwl_lib_ops { /* set hw dependent parameters */ - int (*set_hw_params)(struct iwl_priv *priv); - /* setup BT Rx handler */ - void (*bt_rx_handler_setup)(struct iwl_priv *priv); - /* setup BT related deferred work */ - void (*bt_setup_deferred_work)(struct iwl_priv *priv); - /* cancel deferred work */ - void (*cancel_deferred_work)(struct iwl_priv *priv); + void (*set_hw_params)(struct iwl_priv *priv); int (*set_channel_switch)(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch); /* device specific configuration */ @@ -95,72 +89,6 @@ struct iwl_lib_ops { void (*temperature)(struct iwl_priv *priv); }; -/* - * @max_ll_items: max number of OTP blocks - * @shadow_ram_support: shadow support for OTP memory - * @led_compensation: compensate on the led on/off time per HW according - * 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 - * @adv_thermal_throttle: support advance thermal throttle - * @support_ct_kill_exit: support ct kill exit condition - * @support_wimax_coexist: support wimax/wifi co-exist - * @plcp_delta_threshold: plcp error rate threshold used to trigger - * radio tuning when there is a high receiving plcp error rate - * @chain_noise_scale: default chain noise scale used for gain computation - * @wd_timeout: TX queues watchdog timeout - * @max_event_log_size: size of event log buffer size for ucode event logging - * @shadow_reg_enable: HW shadhow register bit - * @no_idle_support: do not support idle mode - * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up - * wd_disable: disable watchdog timer - */ -struct iwl_base_params { - int eeprom_size; - int num_of_queues; /* def: HW dependent */ - int num_of_ampdu_queues;/* def: HW dependent */ - /* for iwl_apm_init() */ - u32 pll_cfg_val; - - const u16 max_ll_items; - const bool shadow_ram_support; - u16 led_compensation; - bool adv_thermal_throttle; - bool support_ct_kill_exit; - const bool support_wimax_coexist; - u8 plcp_delta_threshold; - s32 chain_noise_scale; - unsigned int wd_timeout; - u32 max_event_log_size; - const bool shadow_reg_enable; - const bool no_idle_support; - const bool hd_v2; - const bool wd_disable; -}; -/* - * @advanced_bt_coexist: support advanced bt coexist - * @bt_init_traffic_load: specify initial bt traffic load - * @bt_prio_boost: default bt priority boost value - * @agg_time_limit: maximum number of uSec in aggregation - * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode - */ -struct iwl_bt_params { - bool advanced_bt_coexist; - u8 bt_init_traffic_load; - u8 bt_prio_boost; - u16 agg_time_limit; - bool bt_sco_disable; - bool bt_session_2; -}; -/* - * @use_rts_for_aggregation: use rts/cts protection for HT traffic - */ -struct iwl_ht_params { - const bool ht_greenfield_support; /* if used set to true */ - bool use_rts_for_aggregation; - enum ieee80211_smps_mode smps_mode; -}; - /*************************** * L i b * ***************************/ @@ -169,7 +97,7 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int hw_decrypt); int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); -int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, +void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, struct iwl_rxon_context *ctx); void iwl_set_flags_for_band(struct iwl_priv *priv, struct iwl_rxon_context *ctx, @@ -197,6 +125,8 @@ const char *get_ctrl_string(int cmd); void iwl_clear_traffic_stats(struct iwl_priv *priv); void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len); +void iwl_reset_traffic_log(struct iwl_priv *priv); + #else static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv) { @@ -242,8 +172,6 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); void iwl_force_scan_end(struct iwl_priv *priv); void iwl_internal_short_hw_scan(struct iwl_priv *priv); int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); -u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, - const u8 *ta, const u8 *ie, int ie_len, int left); void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); @@ -263,6 +191,10 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) +/* traffic log definitions */ +#define IWL_TRAFFIC_ENTRIES (256) +#define IWL_TRAFFIC_ENTRY_SIZE (64) + /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ @@ -297,12 +229,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) cfg(priv)->bt_params->advanced_bt_coexist; } -static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) -{ - IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); - iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); -} - extern bool bt_siso_mode; #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index fbc3095c7b4..5f96ce105f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 1b20c4fb791..059efabda18 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -61,17 +61,67 @@ * *****************************************************************************/ -#include "iwl-trans.h" +#include <linux/interrupt.h> +#include "iwl-debug.h" -int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, - u32 flags, u16 len, const void *data) +#define __iwl_fn(fn) \ +void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ +{ \ + struct va_format vaf = { \ + .fmt = fmt, \ + }; \ + va_list args; \ + \ + va_start(args, fmt); \ + vaf.va = &args; \ + dev_ ##fn(dev, "%pV", &vaf); \ + trace_iwlwifi_ ##fn(&vaf); \ + va_end(args); \ +} + +__iwl_fn(warn) +__iwl_fn(info) +__iwl_fn(crit) + +void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, + const char *fmt, ...) +{ + struct va_format vaf = { + .fmt = fmt, + }; + va_list args; + + va_start(args, fmt); + vaf.va = &args; + if (!trace_only) { + if (rfkill_prefix) + dev_err(dev, "(RFKILL) %pV", &vaf); + else + dev_err(dev, "%pV", &vaf); + } + trace_iwlwifi_err(&vaf); + va_end(args); +} + +#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) +void __iwl_dbg(struct device *dev, + u32 level, bool limit, const char *function, + const char *fmt, ...) { - struct iwl_host_cmd cmd = { - .id = id, - .len = { len, }, - .data = { data, }, - .flags = flags, + struct va_format vaf = { + .fmt = fmt, }; + va_list args; - return iwl_trans_send_cmd(trans, &cmd); + va_start(args, fmt); + vaf.va = &args; +#ifdef CONFIG_IWLWIFI_DEBUG + if (iwl_have_debug_level(level) && + (!limit || net_ratelimit())) + dev_err(dev, "%c %s %pV", in_interrupt() ? 'I' : 'U', + function, &vaf); +#endif + trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); + va_end(args); } +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index f8fc2393dd4..a6b32a11e10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * @@ -29,16 +29,34 @@ #ifndef __iwl_debug_h__ #define __iwl_debug_h__ -#include "iwl-bus.h" #include "iwl-shared.h" +#include "iwl-devtrace.h" struct iwl_priv; -/*No matter what is m (priv, bus, trans), this will work */ -#define IWL_ERR(m, f, a...) dev_err(bus(m)->dev, f, ## a) -#define IWL_WARN(m, f, a...) dev_warn(bus(m)->dev, f, ## a) -#define IWL_INFO(m, f, a...) dev_info(bus(m)->dev, f, ## a) -#define IWL_CRIT(m, f, a...) dev_crit(bus(m)->dev, f, ## a) +void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace, + const char *fmt, ...); +void __iwl_warn(struct device *dev, const char *fmt, ...); +void __iwl_info(struct device *dev, const char *fmt, ...); +void __iwl_crit(struct device *dev, const char *fmt, ...); + +/* No matter what is m (priv, bus, trans), this will work */ +#define IWL_ERR(m, f, a...) __iwl_err(trans(m)->dev, false, false, f, ## a) +#define IWL_WARN(m, f, a...) __iwl_warn(trans(m)->dev, f, ## a) +#define IWL_INFO(m, f, a...) __iwl_info(trans(m)->dev, f, ## a) +#define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) + +#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) +void __iwl_dbg(struct device *dev, + u32 level, bool limit, const char *function, + const char *fmt, ...); +#else +static inline void +__iwl_dbg(struct device *dev, + u32 level, bool limit, const char *function, + const char *fmt, ...) +{} +#endif #define iwl_print_hex_error(m, p, len) \ do { \ @@ -46,54 +64,20 @@ do { \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ } while (0) -#ifdef CONFIG_IWLWIFI_DEBUG -#define IWL_DEBUG(m, level, fmt, ...) \ -do { \ - if (iwl_get_debug_level((m)->shrd) & (level)) \ - dev_err(bus(m)->dev, "%c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __func__, \ - ##__VA_ARGS__); \ -} while (0) - -#define IWL_DEBUG_LIMIT(m, level, fmt, ...) \ -do { \ - if (iwl_get_debug_level((m)->shrd) & (level) && \ - net_ratelimit()) \ - dev_err(bus(m)->dev, "%c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __func__, \ - ##__VA_ARGS__); \ -} while (0) +#define IWL_DEBUG(m, level, fmt, args...) \ + __iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args) +#define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ + __iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args) +#ifdef CONFIG_IWLWIFI_DEBUG #define iwl_print_hex_dump(m, level, p, len) \ do { \ - if (iwl_get_debug_level((m)->shrd) & level) \ + if (iwl_have_debug_level(level)) \ print_hex_dump(KERN_DEBUG, "iwl data: ", \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ } while (0) - -#define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \ -do { \ - if (!iwl_is_rfkill(p->shrd)) \ - dev_err(bus(p)->dev, "%s%c %s " fmt, \ - "", \ - in_interrupt() ? 'I' : 'U', __func__, \ - ##__VA_ARGS__); \ - else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ - dev_err(bus(p)->dev, "%s%c %s " fmt, \ - "(RFKILL) ", \ - in_interrupt() ? 'I' : 'U', __func__, \ - ##__VA_ARGS__); \ -} while (0) - #else -#define IWL_DEBUG(m, level, fmt, args...) -#define IWL_DEBUG_LIMIT(m, level, fmt, args...) #define iwl_print_hex_dump(m, level, p, len) -#define IWL_DEBUG_QUIET_RFKILL(p, fmt, args...) \ -do { \ - if (!iwl_is_rfkill(p->shrd)) \ - IWL_ERR(p, fmt, ##args); \ -} while (0) #endif /* CONFIG_IWLWIFI_DEBUG */ #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 04a3343f461..b7b1c04f2fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -230,16 +230,18 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, int pos = 0; int sram; struct iwl_priv *priv = file->private_data; + const struct fw_img *img; size_t bufsz; /* default is to dump the entire data segment */ if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { - struct iwl_trans *trans = trans(priv); priv->dbgfs_sram_offset = 0x800000; - if (trans->shrd->ucode_type == IWL_UCODE_INIT) - priv->dbgfs_sram_len = trans->ucode_init.data.len; - else - priv->dbgfs_sram_len = trans->ucode_rt.data.len; + if (!priv->ucode_loaded) { + IWL_ERR(priv, "No uCode has been loadded.\n"); + return -EINVAL; + } + img = &priv->fw->img[priv->shrd->ucode_type]; + priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; } len = priv->dbgfs_sram_len; @@ -263,7 +265,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, sram = priv->dbgfs_sram_offset & ~0x3; /* read the first u32 from sram */ - val = iwl_read_targ_mem(bus(priv), sram); + val = iwl_read_targ_mem(trans(priv), sram); for (; len; len--) { /* put the address at the start of every line */ @@ -282,7 +284,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, if (++offset == 4) { sram += 4; offset = 0; - val = iwl_read_targ_mem(bus(priv), sram); + val = iwl_read_targ_mem(trans(priv), sram); } /* put in extra spaces and split lines for human readability */ @@ -336,13 +338,14 @@ static ssize_t iwl_dbgfs_wowlan_sram_read(struct file *file, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; + const struct fw_img *img = &priv->fw->img[IWL_UCODE_WOWLAN]; if (!priv->wowlan_sram) return -ENODATA; return simple_read_from_buffer(user_buf, count, ppos, priv->wowlan_sram, - trans(priv)->ucode_wowlan.data.len); + img->sec[IWL_UCODE_SECTION_DATA].len); } static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -455,7 +458,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, char *buf; ssize_t ret; - if (!test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)) + if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -526,32 +529,26 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", test_bit(STATUS_HCMD_ACTIVE, &priv->shrd->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", - test_bit(STATUS_INT_ENABLED, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); + test_bit(STATUS_RF_KILL_HW, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", - test_bit(STATUS_CT_KILL, &priv->shrd->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", - test_bit(STATUS_INIT, &priv->shrd->status)); + test_bit(STATUS_CT_KILL, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", - test_bit(STATUS_ALIVE, &priv->shrd->status)); + test_bit(STATUS_ALIVE, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", - test_bit(STATUS_READY, &priv->shrd->status)); - pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", - test_bit(STATUS_TEMPERATURE, &priv->shrd->status)); + test_bit(STATUS_READY, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", - test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status)); + test_bit(STATUS_GEO_CONFIGURED, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", - test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)); + test_bit(STATUS_EXIT_PENDING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", - test_bit(STATUS_STATISTICS, &priv->shrd->status)); + test_bit(STATUS_STATISTICS, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", - test_bit(STATUS_SCANNING, &priv->shrd->status)); + test_bit(STATUS_SCANNING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", - test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)); + test_bit(STATUS_SCAN_ABORTING, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", - test_bit(STATUS_SCAN_HW, &priv->shrd->status)); + test_bit(STATUS_SCAN_HW, &priv->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", test_bit(STATUS_POWER_PMI, &priv->shrd->status)); pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", @@ -757,14 +754,14 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) return -EINVAL; - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return -EAGAIN; priv->power_data.debug_sleep_level_override = value; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_power_update_mode(priv, true); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return count; } @@ -835,7 +832,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, char *buf; int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (hw_params(priv).max_txq_num * 32 * 8) + 400; + (cfg(priv)->base_params->num_of_queues * 32 * 8) + 400; const u8 *ptr; ssize_t ret; @@ -844,8 +841,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, IWL_ERR(priv, "Can not allocate buffer\n"); return -ENOMEM; } - if (priv->tx_traffic && - (iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) { + if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) { ptr = priv->tx_traffic; pos += scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n", priv->tx_traffic_idx); @@ -863,8 +859,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, } } - if (priv->rx_traffic && - (iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) { + if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) { ptr = priv->rx_traffic; pos += scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n", priv->rx_traffic_idx); @@ -919,6 +914,8 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) int p = 0; u32 flag; + lockdep_assert_held(&priv->statistics.lock); + flag = le32_to_cpu(priv->statistics.flag); p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); @@ -952,7 +949,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, struct statistics_rx_non_phy *delta_general, *max_general; struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -966,6 +963,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + spin_lock_bh(&priv->statistics.lock); ofdm = &priv->statistics.rx_ofdm; cck = &priv->statistics.rx_cck; general = &priv->statistics.rx_non_phy; @@ -1362,6 +1360,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, accum_ht->unsupport_mcs, delta_ht->unsupport_mcs, max_ht->unsupport_mcs); + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1378,7 +1378,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, ssize_t ret; struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -1391,6 +1391,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + spin_lock_bh(&priv->statistics.lock); + tx = &priv->statistics.tx; accum_tx = &priv->accum_stats.tx; delta_tx = &priv->delta_stats.tx; @@ -1540,19 +1542,25 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { pos += scnprintf(buf + pos, bufsz - pos, "tx power: (1/2 dB step)\n"); - if ((cfg(priv)->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) + if ((hw_params(priv).valid_tx_ant & ANT_A) && + tx->tx_power.ant_a) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna A:", tx->tx_power.ant_a); - if ((cfg(priv)->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) + if ((hw_params(priv).valid_tx_ant & ANT_B) && + tx->tx_power.ant_b) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna B:", tx->tx_power.ant_b); - if ((cfg(priv)->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) + if ((hw_params(priv).valid_tx_ant & ANT_C) && + tx->tx_power.ant_c) pos += scnprintf(buf + pos, bufsz - pos, fmt_hex, "antenna C:", tx->tx_power.ant_c); } + + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1572,7 +1580,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; struct statistics_div *div, *accum_div, *delta_div, *max_div; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -1585,6 +1593,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + + spin_lock_bh(&priv->statistics.lock); + general = &priv->statistics.common; dbg = &priv->statistics.common.dbg; div = &priv->statistics.common.div; @@ -1669,6 +1680,9 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, accum_general->num_of_sos_states, delta_general->num_of_sos_states, max_general->num_of_sos_states); + + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1685,16 +1699,16 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, ssize_t ret; struct statistics_bt_activity *bt, *accum_bt; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; if (!priv->bt_enable_flag) return -EINVAL; /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); if (ret) { IWL_ERR(priv, @@ -1712,6 +1726,9 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ + + spin_lock_bh(&priv->statistics.lock); + bt = &priv->statistics.bt_activity; accum_bt = &priv->accum_stats.bt_activity; @@ -1757,6 +1774,8 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, le32_to_cpu(priv->statistics.num_bt_kills), priv->statistics.accum_num_bt_kills); + spin_unlock_bh(&priv->statistics.lock); + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; @@ -1773,7 +1792,7 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; ssize_t ret; - if (!iwl_is_alive(priv->shrd)) + if (!iwl_is_alive(priv)) return -EAGAIN; buf = kzalloc(bufsz, GFP_KERNEL); @@ -2055,7 +2074,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, const size_t bufsz = sizeof(buf); u32 pwrsave_status; - pwrsave_status = iwl_read32(bus(priv), CSR_GP_CNTRL) & + pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK; pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); @@ -2085,9 +2104,9 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, return -EFAULT; /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_send_statistics_request(priv, CMD_SYNC, true); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return count; } @@ -2131,9 +2150,10 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 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)); + if (iwl_is_alive(priv)) { + /* start collecting data now */ + mod_timer(&priv->ucode_trace, jiffies); + } } else { priv->event_log.ucode_trace = false; del_timer_sync(&priv->ucode_trace); @@ -2219,7 +2239,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, const size_t bufsz = sizeof(buf); pos += scnprintf(buf + pos, bufsz - pos, "%u\n", - cfg(priv)->base_params->plcp_delta_threshold); + priv->plcp_delta_threshold); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -2241,10 +2261,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, return -EINVAL; if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) - cfg(priv)->base_params->plcp_delta_threshold = + priv->plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; else - cfg(priv)->base_params->plcp_delta_threshold = plcp; + priv->plcp_delta_threshold = plcp; return count; } @@ -2320,7 +2340,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, if (sscanf(buf, "%d", &flush) != 1) return -EINVAL; - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) return -EFAULT; iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); @@ -2346,7 +2366,7 @@ static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) timeout = IWL_DEF_WD_TIMEOUT; - cfg(priv)->base_params->wd_timeout = timeout; + hw_params(priv).wd_timeout = timeout; iwl_setup_watchdog(priv); return count; } @@ -2409,7 +2429,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, if (cfg(priv)->ht_params) pos += scnprintf(buf + pos, bufsz - pos, "use %s for aggregation\n", - (cfg(priv)->ht_params->use_rts_for_aggregation) ? + (hw_params(priv).use_rts_for_aggregation) ? "rts/cts" : "cts-to-self"); else pos += scnprintf(buf + pos, bufsz - pos, "N/A"); @@ -2436,9 +2456,9 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, if (sscanf(buf, "%d", &rts) != 1) return -EINVAL; if (rts) - cfg(priv)->ht_params->use_rts_for_aggregation = true; + hw_params(priv).use_rts_for_aggregation = true; else - cfg(priv)->ht_params->use_rts_for_aggregation = false; + hw_params(priv).use_rts_for_aggregation = false; return count; } @@ -2484,52 +2504,6 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); -#ifdef CONFIG_IWLWIFI_DEBUG -static ssize_t iwl_dbgfs_debug_level_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - struct iwl_shared *shrd = priv->shrd; - char buf[11]; - int len; - - len = scnprintf(buf, sizeof(buf), "0x%.8x", - iwl_get_debug_level(shrd)); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t iwl_dbgfs_debug_level_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_priv *priv = file->private_data; - struct iwl_shared *shrd = priv->shrd; - char buf[11]; - unsigned long val; - int ret; - - if (count > sizeof(buf)) - return -EINVAL; - - memset(buf, 0, sizeof(buf)); - if (copy_from_user(buf, user_buf, count)) - return -EFAULT; - - ret = strict_strtoul(buf, 0, &val); - if (ret) - return ret; - - shrd->dbg_level_dev = val; - if (iwl_alloc_traffic_mem(priv)) - IWL_ERR(priv, "Not enough memory to generate traffic log\n"); - - return count; -} -DEBUGFS_READ_WRITE_FILE_OPS(debug_level); -#endif /* CONFIG_IWLWIFI_DEBUG */ - /* * Create the debugfs files and directories * @@ -2594,9 +2568,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); -#ifdef CONFIG_IWLWIFI_DEBUG - DEBUGFS_ADD_FILE(debug_level, dir_debug, S_IRUSR | S_IWUSR); -#endif DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e54a4d11e58..16956b777f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 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 @@ -36,20 +36,20 @@ #include <linux/wait.h> #include <linux/leds.h> #include <linux/slab.h> -#include <net/ieee80211_radiotap.h> +#include <linux/mutex.h> #include "iwl-eeprom.h" #include "iwl-csr.h" -#include "iwl-prph.h" #include "iwl-debug.h" #include "iwl-agn-hw.h" #include "iwl-led.h" #include "iwl-power.h" #include "iwl-agn-rs.h" #include "iwl-agn-tt.h" -#include "iwl-bus.h" #include "iwl-trans.h" #include "iwl-shared.h" +#include "iwl-op-mode.h" +#include "iwl-notif-wait.h" struct iwl_tx_queue; @@ -292,117 +292,8 @@ struct iwl_vif_priv { u8 ibss_bssid_sta_id; }; -/* v1/v2 uCode file layout */ -struct iwl_ucode_header { - __le32 ver; /* major/minor/API/serial */ - union { - struct { - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v1; - struct { - __le32 build; /* build number */ - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v2; - } u; -}; - -/* - * new TLV uCode file layout - * - * The new TLV file format contains TLVs, that each specify - * some piece of data. To facilitate "groups", for example - * different instruction image with different capabilities, - * bundled with the same init image, an alternative mechanism - * is provided: - * When the alternative field is 0, that means that the item - * is always valid. When it is non-zero, then it is only - * valid in conjunction with items of the same alternative, - * in which case the driver (user) selects one alternative - * to use. - */ - -enum iwl_ucode_tlv_type { - IWL_UCODE_TLV_INVALID = 0, /* unused */ - IWL_UCODE_TLV_INST = 1, - IWL_UCODE_TLV_DATA = 2, - IWL_UCODE_TLV_INIT = 3, - IWL_UCODE_TLV_INIT_DATA = 4, - IWL_UCODE_TLV_BOOT = 5, - IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ - IWL_UCODE_TLV_PAN = 7, - IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, - IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, - IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, - IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, - IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, - IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, - IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, - IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, - IWL_UCODE_TLV_WOWLAN_INST = 16, - IWL_UCODE_TLV_WOWLAN_DATA = 17, - IWL_UCODE_TLV_FLAGS = 18, -}; - -/** - * enum iwl_ucode_tlv_flag - ucode API flags - * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously - * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, - * treats good CRC threshold as a boolean - * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). - * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. - */ -enum iwl_ucode_tlv_flag { - IWL_UCODE_TLV_FLAGS_PAN = BIT(0), - IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), - IWL_UCODE_TLV_FLAGS_MFP = BIT(2), - IWL_UCODE_TLV_FLAGS_P2P = BIT(3), -}; - -struct iwl_ucode_tlv { - __le16 type; /* see above */ - __le16 alternative; /* see comment */ - __le32 length; /* not including type/length fields */ - u8 data[0]; -} __packed; - -#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 - -struct iwl_tlv_ucode_header { - /* - * The TLV style ucode header is distinguished from - * the v1/v2 style header by first four bytes being - * zero, as such is an invalid combination of - * major/minor/API/serial versions. - */ - __le32 zero; - __le32 magic; - u8 human_readable[64]; - __le32 ver; /* major/minor/API/serial */ - __le32 build; - __le64 alternatives; /* bitmask of valid alternatives */ - /* - * The data contained herein has a TLV layout, - * see above for the TLV header and types. - * Note that each TLV is padded to a length - * that is a multiple of 4 for alignment. - */ - u8 data[0]; -}; - struct iwl_sensitivity_ranges { u16 min_nrg_cck; - u16 max_nrg_cck; u16 nrg_th_cck; u16 nrg_th_ofdm; @@ -550,9 +441,6 @@ struct iwl_chain_noise_data { u8 state; }; -#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ -#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ - enum { MEASUREMENT_READY = (1 << 0), MEASUREMENT_ACTIVE = (1 << 1), @@ -661,7 +549,7 @@ struct traffic_stats { * 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) +#define UCODE_TRACE_PERIOD (10) /* * iwl_event_log: current uCode event log position @@ -781,11 +669,6 @@ struct iwl_rxon_context { bool enabled, is_40mhz; u8 extension_chan_offset; } ht; - - u8 bssid[ETH_ALEN]; - bool preauth_bssid; - - bool last_tx_rejected; }; enum iwl_scan_type { @@ -804,11 +687,11 @@ struct iwl_testmode_trace { dma_addr_t dma_addr; bool trace_enabled; }; -struct iwl_testmode_sram { +struct iwl_testmode_mem { u32 buff_size; u32 num_chunks; u8 *buff_addr; - bool sram_readed; + bool read_in_progress; }; #endif @@ -818,32 +701,55 @@ struct iwl_wipan_noa_data { u8 data[]; }; +#define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ + ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) + +#define IWL_MAC80211_GET_DVM(_hw) \ + ((struct iwl_priv *) ((struct iwl_op_mode *) \ + (_hw)->priv)->op_mode_specific) + struct iwl_priv { /*data shared among all the driver's layers */ - struct iwl_shared _shrd; struct iwl_shared *shrd; + const struct iwl_fw *fw; + unsigned long status; + + spinlock_t sta_lock; + struct mutex mutex; + + unsigned long transport_queue_stop; + bool passive_no_rx; /* ieee device used by generic ieee processing code */ struct ieee80211_hw *hw; struct ieee80211_channel *ieee_channels; struct ieee80211_rate *ieee_rates; - struct kmem_cache *tx_cmd_pool; + + struct list_head calib_results; + + struct workqueue_struct *workqueue; enum ieee80211_band band; void (*pre_rx_handler)(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); + struct iwl_rx_cmd_buffer *rxb); int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); + struct iwl_notif_wait_data notif_wait; + struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; /* spectrum measurement report caching */ struct iwl_spectrum_notification measure_report; u8 measurement_status; +#define IWL_OWNERSHIP_DRIVER 0 +#define IWL_OWNERSHIP_TM 1 + u8 ucode_owner; + /* ucode beacon time */ u32 ucode_beacon_time; int missed_beacon_threshold; @@ -863,12 +769,16 @@ struct iwl_priv { /* firmware reload counter and timestamp */ unsigned long reload_jiffies; int reload_count; + bool ucode_loaded; + bool init_ucode_run; /* Don't run init uCode again */ /* we allocate array of iwl_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ struct iwl_channel_info *channel_info; /* channel info array */ u8 channel_count; /* # of channels */ + u8 plcp_delta_threshold; + /* thermal calibration */ s32 temperature; /* Celsius */ s32 last_temperature; @@ -891,16 +801,11 @@ struct iwl_priv { bool new_scan_threshold_behaviour; + bool wowlan; + /* EEPROM MAC addresses */ struct mac_address addresses[2]; - /* uCode images, save to reload in case of failure */ - int fw_index; /* firmware we're trying to load */ - u32 ucode_ver; /* version of ucode, copy of - iwl_ucode.ver */ - - char firmware_name[25]; - struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; __le16 switch_channel; @@ -910,7 +815,6 @@ struct iwl_priv { u8 start_calib; struct iwl_sensitivity_data sensitivity_data; struct iwl_chain_noise_data chain_noise_data; - bool enhance_sensitivity_table; __le16 sensitivity_tbl[HD_TABLE_SIZE]; __le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES]; @@ -956,6 +860,7 @@ struct iwl_priv { struct statistics_bt_activity bt_activity; __le32 num_bt_kills, accum_num_bt_kills; #endif + spinlock_t lock; } statistics; #ifdef CONFIG_IWLWIFI_DEBUGFS struct { @@ -978,11 +883,6 @@ struct iwl_priv { struct iwl_rx_phy_res last_phy_res; bool last_phy_res_valid; - struct completion firmware_loading_complete; - - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; - /* * chain noise reset and gain commands are the * two extra calibration commands follows the standard @@ -1073,7 +973,7 @@ struct iwl_priv { bool led_registered; #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE struct iwl_testmode_trace testmode_trace; - struct iwl_testmode_sram testmode_sram; + struct iwl_testmode_mem testmode_mem; u32 tm_fixed_rate; #endif @@ -1084,6 +984,7 @@ struct iwl_priv { bool have_rekey_data; }; /*iwl_priv */ +extern struct kmem_cache *iwl_tx_cmd_pool; extern struct iwl_mod_params iwlagn_mod_params; static inline struct iwl_rxon_context * diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 2a2c8de64a0..91f45e71e0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2012 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 9b212a8f30b..06203d6a1d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2012 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 @@ -34,185 +34,254 @@ #undef TRACE_EVENT #define TRACE_EVENT(name, proto, ...) \ static inline void trace_ ## name(proto) {} +#undef DECLARE_EVENT_CLASS +#define DECLARE_EVENT_CLASS(...) +#undef DEFINE_EVENT +#define DEFINE_EVENT(evt_class, name, proto, ...) \ +static inline void trace_ ## name(proto) {} #endif -#define PRIV_ENTRY __field(void *, priv) -#define PRIV_ASSIGN __entry->priv = priv +#define DEV_ENTRY __string(dev, dev_name(dev)) +#define DEV_ASSIGN __assign_str(dev, dev_name(dev)) #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_io TRACE_EVENT(iwlwifi_dev_ioread32, - TP_PROTO(void *priv, u32 offs, u32 val), - TP_ARGS(priv, offs, val), + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, offs) __field(u32, val) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->offs = offs; __entry->val = val; ), - TP_printk("[%p] read io[%#x] = %#x", __entry->priv, __entry->offs, __entry->val) + TP_printk("[%s] read io[%#x] = %#x", + __get_str(dev), __entry->offs, __entry->val) ); TRACE_EVENT(iwlwifi_dev_iowrite8, - TP_PROTO(void *priv, u32 offs, u8 val), - TP_ARGS(priv, offs, val), + TP_PROTO(const struct device *dev, u32 offs, u8 val), + TP_ARGS(dev, offs, val), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, offs) __field(u8, val) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->offs = offs; __entry->val = val; ), - TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) + TP_printk("[%s] write io[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) ); TRACE_EVENT(iwlwifi_dev_iowrite32, - TP_PROTO(void *priv, u32 offs, u32 val), - TP_ARGS(priv, offs, val), + TP_PROTO(const struct device *dev, u32 offs, u32 val), + TP_ARGS(dev, offs, val), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, offs) __field(u32, val) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->offs = offs; __entry->val = val; ), - TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) + TP_printk("[%s] write io[%#x] = %#x)", + __get_str(dev), __entry->offs, __entry->val) ); TRACE_EVENT(iwlwifi_dev_irq, - TP_PROTO(void *priv), - TP_ARGS(priv), + TP_PROTO(const struct device *dev), + TP_ARGS(dev), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; ), /* TP_printk("") doesn't compile */ TP_printk("%d", 0) ); TRACE_EVENT(iwlwifi_dev_ict_read, - TP_PROTO(void *priv, u32 index, u32 value), - TP_ARGS(priv, index, value), + TP_PROTO(const struct device *dev, u32 index, u32 value), + TP_ARGS(dev, index, value), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, index) __field(u32, value) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->index = index; __entry->value = value; ), - TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value) + TP_printk("[%s] read ict[%d] = %#.8x", + __get_str(dev), __entry->index, __entry->value) ); #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_ucode TRACE_EVENT(iwlwifi_dev_ucode_cont_event, - TP_PROTO(void *priv, u32 time, u32 data, u32 ev), - TP_ARGS(priv, time, data, ev), + TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), + TP_ARGS(dev, time, data, ev), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, time) __field(u32, data) __field(u32, ev) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_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) + TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", + __get_str(dev), __entry->time, __entry->data, __entry->ev) ); TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, - TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), - TP_ARGS(priv, wraps, n_entry, p_entry), + TP_PROTO(const struct device *dev, u32 wraps, u32 n_entry, u32 p_entry), + TP_ARGS(dev, wraps, n_entry, p_entry), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, wraps) __field(u32, n_entry) __field(u32, p_entry) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_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, + TP_printk("[%s] wraps=#%02d n=0x%X p=0x%X", + __get_str(dev), __entry->wraps, __entry->n_entry, __entry->p_entry) ); #undef TRACE_SYSTEM +#define TRACE_SYSTEM iwlwifi_msg + +#define MAX_MSG_LEN 100 + +DECLARE_EVENT_CLASS(iwlwifi_msg_event, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf), + TP_STRUCT__entry( + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s", (char *)__get_dynamic_array(msg)) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_err, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_warn, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_info, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +DEFINE_EVENT(iwlwifi_msg_event, iwlwifi_crit, + TP_PROTO(struct va_format *vaf), + TP_ARGS(vaf) +); + +TRACE_EVENT(iwlwifi_dbg, + TP_PROTO(u32 level, bool in_interrupt, const char *function, + struct va_format *vaf), + TP_ARGS(level, in_interrupt, function, vaf), + TP_STRUCT__entry( + __field(u32, level) + __field(u8, in_interrupt) + __string(function, function) + __dynamic_array(char, msg, MAX_MSG_LEN) + ), + TP_fast_assign( + __entry->level = level; + __entry->in_interrupt = in_interrupt; + __assign_str(function, function); + WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), + MAX_MSG_LEN, vaf->fmt, + *vaf->va) >= MAX_MSG_LEN); + ), + TP_printk("%s", (char *)__get_dynamic_array(msg)) +); + +#undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi TRACE_EVENT(iwlwifi_dev_hcmd, - TP_PROTO(void *priv, u32 flags, + TP_PROTO(const struct device *dev, u32 flags, const void *hcmd0, size_t len0, const void *hcmd1, size_t len1, const void *hcmd2, size_t len2), - TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), + TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __dynamic_array(u8, hcmd0, len0) __dynamic_array(u8, hcmd1, len1) __dynamic_array(u8, hcmd2, len2) __field(u32, flags) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; memcpy(__get_dynamic_array(hcmd0), hcmd0, len0); memcpy(__get_dynamic_array(hcmd1), hcmd1, len1); memcpy(__get_dynamic_array(hcmd2), hcmd2, len2); __entry->flags = flags; ), - TP_printk("[%p] hcmd %#.2x (%ssync)", - __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0], + TP_printk("[%s] hcmd %#.2x (%ssync)", + __get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0], __entry->flags & CMD_ASYNC ? "a" : "") ); TRACE_EVENT(iwlwifi_dev_rx, - TP_PROTO(void *priv, void *rxbuf, size_t len), - TP_ARGS(priv, rxbuf, len), + TP_PROTO(const struct device *dev, void *rxbuf, size_t len), + TP_ARGS(dev, rxbuf, len), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __dynamic_array(u8, rxbuf, len) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; memcpy(__get_dynamic_array(rxbuf), rxbuf, len); ), - TP_printk("[%p] RX cmd %#.2x", - __entry->priv, ((u8 *)__get_dynamic_array(rxbuf))[4]) + TP_printk("[%s] RX cmd %#.2x", + __get_str(dev), ((u8 *)__get_dynamic_array(rxbuf))[4]) ); TRACE_EVENT(iwlwifi_dev_tx, - TP_PROTO(void *priv, void *tfd, size_t tfdlen, + TP_PROTO(const struct device *dev, void *tfd, size_t tfdlen, void *buf0, size_t buf0_len, void *buf1, size_t buf1_len), - TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), + TP_ARGS(dev, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(size_t, framelen) __dynamic_array(u8, tfd, tfdlen) @@ -226,29 +295,28 @@ TRACE_EVENT(iwlwifi_dev_tx, __dynamic_array(u8, buf1, buf1_len) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->framelen = buf0_len + buf1_len; memcpy(__get_dynamic_array(tfd), tfd, tfdlen); memcpy(__get_dynamic_array(buf0), buf0, buf0_len); memcpy(__get_dynamic_array(buf1), buf1, buf1_len); ), - TP_printk("[%p] TX %.2x (%zu bytes)", - __entry->priv, - ((u8 *)__get_dynamic_array(buf0))[0], + TP_printk("[%s] TX %.2x (%zu bytes)", + __get_str(dev), ((u8 *)__get_dynamic_array(buf0))[0], __entry->framelen) ); TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(void *priv, u32 desc, u32 tsf_low, + TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, u32 data1, u32 data2, u32 line, u32 blink1, u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, u32 brd_ver), - TP_ARGS(priv, desc, tsf_low, data1, data2, line, + TP_ARGS(dev, desc, tsf_low, data1, data2, line, blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, gp3, ucode_ver, hw_ver, brd_ver), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, desc) __field(u32, tsf_low) __field(u32, data1) @@ -267,7 +335,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __field(u32, brd_ver) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_ASSIGN; __entry->desc = desc; __entry->tsf_low = tsf_low; __entry->data1 = data1; @@ -285,11 +353,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, __entry->hw_ver = hw_ver; __entry->brd_ver = brd_ver; ), - TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " + TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " "hw 0x%08X brd 0x%08X", - __entry->priv, __entry->desc, __entry->tsf_low, + __get_str(dev), __entry->desc, __entry->tsf_low, __entry->data1, __entry->data2, __entry->line, __entry->blink1, __entry->blink2, __entry->ilink1, __entry->ilink2, @@ -299,23 +367,23 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, ); TRACE_EVENT(iwlwifi_dev_ucode_event, - TP_PROTO(void *priv, u32 time, u32 data, u32 ev), - TP_ARGS(priv, time, data, ev), + TP_PROTO(const struct device *dev, u32 time, u32 data, u32 ev), + TP_ARGS(dev, time, data, ev), TP_STRUCT__entry( - PRIV_ENTRY + DEV_ENTRY __field(u32, time) __field(u32, data) __field(u32, ev) ), TP_fast_assign( - PRIV_ASSIGN; + DEV_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) + TP_printk("[%s] EVT_LOGT:%010u:0x%08x:%04u", + __get_str(dev), __entry->time, __entry->data, __entry->ev) ); #endif /* __IWLWIFI_DEVICE_TRACE */ diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c new file mode 100644 index 00000000000..6f312c77af5 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -0,0 +1,993 @@ +/****************************************************************************** + * + * 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 - 2012 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 - 2012 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/completion.h> +#include <linux/dma-mapping.h> +#include <linux/firmware.h> +#include <linux/module.h> + +#include "iwl-drv.h" +#include "iwl-trans.h" +#include "iwl-shared.h" +#include "iwl-op-mode.h" +#include "iwl-agn-hw.h" + +/* private includes */ +#include "iwl-fw-file.h" + +/** + * struct iwl_drv - drv common data + * @fw: the iwl_fw structure + * @shrd: pointer to common shared structure + * @op_mode: the running op_mode + * @fw_index: firmware revision to try loading + * @firmware_name: composite filename of ucode file to load + * @request_firmware_complete: the firmware has been obtained from user space + */ +struct iwl_drv { + struct iwl_fw fw; + + struct iwl_shared *shrd; + struct iwl_op_mode *op_mode; + + int fw_index; /* firmware we're trying to load */ + char firmware_name[25]; /* name of firmware file to load */ + + struct completion request_firmware_complete; +}; + + + +/* + * struct fw_sec: Just for the image parsing proccess. + * For the fw storage we are using struct fw_desc. + */ +struct fw_sec { + const void *data; /* the sec data */ + size_t size; /* section size */ + u32 offset; /* offset of writing in the device */ +}; + +static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) +{ + if (desc->v_addr) + dma_free_coherent(trans(drv)->dev, desc->len, + desc->v_addr, desc->p_addr); + desc->v_addr = NULL; + desc->len = 0; +} + +static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) +{ + int i; + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) + iwl_free_fw_desc(drv, &img->sec[i]); +} + +static void iwl_dealloc_ucode(struct iwl_drv *drv) +{ + int i; + for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) + iwl_free_fw_img(drv, drv->fw.img + i); +} + +static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, + struct fw_sec *sec) +{ + if (!sec || !sec->size) { + desc->v_addr = NULL; + return -EINVAL; + } + + desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size, + &desc->p_addr, GFP_KERNEL); + if (!desc->v_addr) + return -ENOMEM; + + desc->len = sec->size; + desc->offset = sec->offset; + memcpy(desc->v_addr, sec->data, sec->size); + return 0; +} + +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); + +#define UCODE_EXPERIMENTAL_INDEX 100 +#define UCODE_EXPERIMENTAL_TAG "exp" + +static int iwl_request_firmware(struct iwl_drv *drv, bool first) +{ + const struct iwl_cfg *cfg = cfg(drv); + const char *name_pre = cfg->fw_name_pre; + char tag[8]; + + if (first) { +#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + drv->fw_index = UCODE_EXPERIMENTAL_INDEX; + strcpy(tag, UCODE_EXPERIMENTAL_TAG); + } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) { +#endif + drv->fw_index = cfg->ucode_api_max; + sprintf(tag, "%d", drv->fw_index); + } else { + drv->fw_index--; + sprintf(tag, "%d", drv->fw_index); + } + + if (drv->fw_index < cfg->ucode_api_min) { + IWL_ERR(drv, "no suitable firmware found!\n"); + return -ENOENT; + } + + sprintf(drv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + + IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n", + (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? "EXPERIMENTAL " : "", + drv->firmware_name); + + return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, + trans(drv)->dev, + GFP_KERNEL, drv, iwl_ucode_callback); +} + +struct fw_img_parsing { + struct fw_sec sec[IWL_UCODE_SECTION_MAX]; + int sec_counter; +}; + +/* + * struct fw_sec_parsing: to extract fw section and it's offset from tlv + */ +struct fw_sec_parsing { + __le32 offset; + const u8 data[]; +} __packed; + +/** + * struct iwl_tlv_calib_data - parse the default calib data from TLV + * + * @ucode_type: the uCode to which the following default calib relates. + * @calib: default calibrations. + */ +struct iwl_tlv_calib_data { + __le32 ucode_type; + __le64 calib; +} __packed; + +struct iwl_firmware_pieces { + struct fw_img_parsing img[IWL_UCODE_TYPE_MAX]; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; +}; + +/* + * These functions are just to extract uCode section data from the pieces + * structure. + */ +static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + return &pieces->img[type].sec[sec]; +} + +static void set_sec_data(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + const void *data) +{ + pieces->img[type].sec[sec].data = data; +} + +static void set_sec_size(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + size_t size) +{ + pieces->img[type].sec[sec].size = size; +} + +static size_t get_sec_size(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + return pieces->img[type].sec[sec].size; +} + +static void set_sec_offset(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec, + u32 offset) +{ + pieces->img[type].sec[sec].offset = offset; +} + +/* + * Gets uCode section from tlv. + */ +static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, + const void *data, enum iwl_ucode_type type, + int size) +{ + struct fw_img_parsing *img; + struct fw_sec *sec; + struct fw_sec_parsing *sec_parse; + + if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX)) + return -1; + + sec_parse = (struct fw_sec_parsing *)data; + + img = &pieces->img[type]; + sec = &img->sec[img->sec_counter]; + + sec->offset = le32_to_cpu(sec_parse->offset); + sec->data = sec_parse->data; + + ++img->sec_counter; + + return 0; +} + +static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data) +{ + struct iwl_tlv_calib_data *def_calib = + (struct iwl_tlv_calib_data *)data; + u32 ucode_type = le32_to_cpu(def_calib->ucode_type); + if (ucode_type >= IWL_UCODE_TYPE_MAX) { + IWL_ERR(drv, "Wrong ucode_type %u for default calibration.\n", + ucode_type); + return -EINVAL; + } + drv->fw.default_calib[ucode_type] = le64_to_cpu(def_calib->calib); + return 0; +} + +static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv, + const struct firmware *ucode_raw, + struct iwl_firmware_pieces *pieces) +{ + struct iwl_ucode_header *ucode = (void *)ucode_raw->data; + u32 api_ver, hdr_size, build; + char buildstr[25]; + const u8 *src; + + drv->fw.ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(drv->fw.ucode_ver); + + switch (api_ver) { + default: + hdr_size = 28; + if (ucode_raw->size < hdr_size) { + IWL_ERR(drv, "File size too small!\n"); + return -EINVAL; + } + build = le32_to_cpu(ucode->u.v2.build); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v2.inst_size)); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v2.data_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v2.init_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v2.init_data_size)); + src = ucode->u.v2.data; + break; + case 0: + case 1: + case 2: + hdr_size = 24; + if (ucode_raw->size < hdr_size) { + IWL_ERR(drv, "File size too small!\n"); + return -EINVAL; + } + build = 0; + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v1.inst_size)); + set_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v1.data_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + le32_to_cpu(ucode->u.v1.init_size)); + set_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + le32_to_cpu(ucode->u.v1.init_data_size)); + src = ucode->u.v1.data; + break; + } + + if (build) + sprintf(buildstr, " build %u%s", build, + (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(drv->fw.ucode_ver), + IWL_UCODE_MINOR(drv->fw.ucode_ver), + IWL_UCODE_API(drv->fw.ucode_ver), + IWL_UCODE_SERIAL(drv->fw.ucode_ver), + buildstr); + + /* Verify size of file vs. image size info in file's header */ + + if (ucode_raw->size != hdr_size + + get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) + + get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) + + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) + + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)) { + + IWL_ERR(drv, + "uCode file size %d does not match expected size\n", + (int)ucode_raw->size); + return -EINVAL; + } + + + set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, src); + src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST); + set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, src); + src += get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA); + set_sec_offset(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, src); + src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST); + set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + set_sec_data(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, src); + src += get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA); + set_sec_offset(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + return 0; +} + +static int iwl_parse_tlv_firmware(struct iwl_drv *drv, + const struct firmware *ucode_raw, + struct iwl_firmware_pieces *pieces, + struct iwl_ucode_capabilities *capa) +{ + struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; + struct iwl_ucode_tlv *tlv; + size_t len = ucode_raw->size; + const u8 *data; + int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; + int tmp; + u64 alternatives; + u32 tlv_len; + enum iwl_ucode_tlv_type tlv_type; + const u8 *tlv_data; + char buildstr[25]; + u32 build; + + if (len < sizeof(*ucode)) { + IWL_ERR(drv, "uCode has invalid length: %zd\n", len); + return -EINVAL; + } + + if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { + IWL_ERR(drv, "invalid uCode magic: 0X%x\n", + le32_to_cpu(ucode->magic)); + return -EINVAL; + } + + /* + * Check which alternatives are present, and "downgrade" + * when the chosen alternative is not present, warning + * the user when that happens. Some files may not have + * any alternatives, so don't warn in that case. + */ + alternatives = le64_to_cpu(ucode->alternatives); + tmp = wanted_alternative; + if (wanted_alternative > 63) + wanted_alternative = 63; + while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) + wanted_alternative--; + if (wanted_alternative && wanted_alternative != tmp) + IWL_WARN(drv, + "uCode alternative %d not available, choosing %d\n", + tmp, wanted_alternative); + + drv->fw.ucode_ver = le32_to_cpu(ucode->ver); + build = le32_to_cpu(ucode->build); + + if (build) + sprintf(buildstr, " build %u%s", build, + (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + snprintf(drv->fw.fw_version, + sizeof(drv->fw.fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(drv->fw.ucode_ver), + IWL_UCODE_MINOR(drv->fw.ucode_ver), + IWL_UCODE_API(drv->fw.ucode_ver), + IWL_UCODE_SERIAL(drv->fw.ucode_ver), + buildstr); + + data = ucode->data; + + len -= sizeof(*ucode); + + while (len >= sizeof(*tlv)) { + u16 tlv_alt; + + len -= sizeof(*tlv); + tlv = (void *)data; + + tlv_len = le32_to_cpu(tlv->length); + tlv_type = le16_to_cpu(tlv->type); + tlv_alt = le16_to_cpu(tlv->alternative); + tlv_data = tlv->data; + + if (len < tlv_len) { + IWL_ERR(drv, "invalid TLV len: %zd/%u\n", + len, tlv_len); + return -EINVAL; + } + len -= ALIGN(tlv_len, 4); + data += sizeof(*tlv) + ALIGN(tlv_len, 4); + + /* + * Alternative 0 is always valid. + * + * Skip alternative TLVs that are not selected. + */ + if (tlv_alt != 0 && tlv_alt != wanted_alternative) + continue; + + switch (tlv_type) { + case IWL_UCODE_TLV_INST: + set_sec_data(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + break; + case IWL_UCODE_TLV_DATA: + set_sec_data(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + break; + case IWL_UCODE_TLV_INIT: + set_sec_data(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + break; + case IWL_UCODE_TLV_INIT_DATA: + set_sec_data(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + break; + case IWL_UCODE_TLV_BOOT: + IWL_ERR(drv, "Found unexpected BOOT ucode\n"); + break; + case IWL_UCODE_TLV_PROBE_MAX_LEN: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->max_probe_length = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_PAN: + if (tlv_len) + goto invalid_tlv_len; + capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; + break; + case IWL_UCODE_TLV_FLAGS: + /* must be at least one u32 */ + if (tlv_len < sizeof(u32)) + goto invalid_tlv_len; + /* and a proper number of u32s */ + if (tlv_len % sizeof(u32)) + goto invalid_tlv_len; + /* + * This driver only reads the first u32 as + * right now no more features are defined, + * if that changes then either the driver + * will not work with the new firmware, or + * it'll not take advantage of new features. + */ + capa->flags = le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_ENHANCE_SENS_TBL: + if (tlv_len) + goto invalid_tlv_len; + drv->fw.enhance_sensitivity_table = true; + break; + case IWL_UCODE_TLV_WOWLAN_INST: + set_sec_data(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, tlv_data); + set_sec_size(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, tlv_len); + set_sec_offset(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_INST, + IWLAGN_RTC_INST_LOWER_BOUND); + break; + case IWL_UCODE_TLV_WOWLAN_DATA: + set_sec_data(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, tlv_data); + set_sec_size(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, tlv_len); + set_sec_offset(pieces, IWL_UCODE_WOWLAN, + IWL_UCODE_SECTION_DATA, + IWLAGN_RTC_DATA_LOWER_BOUND); + break; + case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->standard_phy_calibration_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_SEC_RT: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, + tlv_len); + drv->fw.mvm_fw = true; + break; + case IWL_UCODE_TLV_SEC_INIT: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, + tlv_len); + drv->fw.mvm_fw = true; + break; + case IWL_UCODE_TLV_SEC_WOWLAN: + iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, + tlv_len); + drv->fw.mvm_fw = true; + break; + case IWL_UCODE_TLV_DEF_CALIB: + if (tlv_len != sizeof(struct iwl_tlv_calib_data)) + goto invalid_tlv_len; + if (iwl_set_default_calib(drv, tlv_data)) + goto tlv_error; + break; + case IWL_UCODE_TLV_PHY_SKU: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); + break; + default: + IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); + break; + } + } + + if (len) { + IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); + return -EINVAL; + } + + return 0; + + invalid_tlv_len: + IWL_ERR(drv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + tlv_error: + iwl_print_hex_dump(drv, IWL_DL_FW, tlv_data, tlv_len); + + return -EINVAL; +} + +static int alloc_pci_desc(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type) +{ + int i; + for (i = 0; + i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); + i++) + if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), + get_sec(pieces, type, i))) + return -1; + return 0; +} + +static int validate_sec_sizes(struct iwl_drv *drv, + struct iwl_firmware_pieces *pieces, + const struct iwl_cfg *cfg) +{ + IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", + get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); + + /* Verify that uCode images will fit in card's SRAM. */ + if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_INIT, + IWL_UCODE_SECTION_INST)); + return -1; + } + + if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", + get_sec_size(pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + return -1; + } + return 0; +} + + +/** + * iwl_ucode_callback - callback when firmware was loaded + * + * If loaded successfully, copies the firmware into buffers + * for the card to fetch (via DMA). + */ +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) +{ + struct iwl_drv *drv = context; + const struct iwl_cfg *cfg = cfg(drv); + struct iwl_fw *fw = &drv->fw; + struct iwl_ucode_header *ucode; + int err; + struct iwl_firmware_pieces pieces; + const unsigned int api_max = cfg->ucode_api_max; + unsigned int api_ok = cfg->ucode_api_ok; + const unsigned int api_min = cfg->ucode_api_min; + u32 api_ver; + int i; + + fw->ucode_capa.max_probe_length = 200; + fw->ucode_capa.standard_phy_calibration_size = + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + if (!api_ok) + api_ok = api_max; + + memset(&pieces, 0, sizeof(pieces)); + + if (!ucode_raw) { + if (drv->fw_index <= api_ok) + IWL_ERR(drv, + "request for firmware file '%s' failed.\n", + drv->firmware_name); + goto try_again; + } + + IWL_DEBUG_INFO(drv, "Loaded firmware file '%s' (%zd bytes).\n", + drv->firmware_name, ucode_raw->size); + + /* Make sure that we got at least the API version number */ + if (ucode_raw->size < 4) { + IWL_ERR(drv, "File size way too small!\n"); + goto try_again; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + if (ucode->ver) + err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); + else + err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, + &fw->ucode_capa); + + if (err) + goto try_again; + + api_ver = IWL_UCODE_API(drv->fw.ucode_ver); + + /* + * api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward + */ + /* no api version check required for experimental uCode */ + if (drv->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(drv, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } + + if (api_ver < api_ok) { + if (api_ok != api_max) + IWL_ERR(drv, "Firmware has old API version, " + "expected v%u through v%u, got v%u.\n", + api_ok, api_max, api_ver); + else + IWL_ERR(drv, "Firmware has old API version, " + "expected v%u, got v%u.\n", + api_max, api_ver); + IWL_ERR(drv, "New firmware can be obtained from " + "http://www.intellinuxwireless.org/.\n"); + } + } + + IWL_INFO(drv, "loaded firmware version %s", drv->fw.fw_version); + + /* + * For any of the failures below (before allocating pci memory) + * we will try to load a version with a smaller API -- maybe the + * user just got a corrupted version of the latest API. + */ + + IWL_DEBUG_INFO(drv, "f/w package hdr ucode version raw = 0x%x\n", + drv->fw.ucode_ver); + IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); + IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", + get_sec_size(&pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); + + /* Verify that uCode images will fit in card's SRAM */ + if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > + cfg->max_inst_size) { + IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_INST)); + goto try_again; + } + + if (get_sec_size(&pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > + cfg->max_data_size) { + IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", + get_sec_size(&pieces, IWL_UCODE_REGULAR, + IWL_UCODE_SECTION_DATA)); + goto try_again; + } + + /* + * In mvm uCode there is no difference between data and instructions + * sections. + */ + if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg)) + goto try_again; + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) + if (alloc_pci_desc(drv, &pieces, i)) + goto err_pci_alloc; + + /* Now that we can no longer fail, copy information */ + + /* + * The (size - 16) / 12 formula is based on the information recorded + * for each event, which is of mode 1 (including timestamp) for all + * new microcodes that include this information. + */ + fw->init_evtlog_ptr = pieces.init_evtlog_ptr; + if (pieces.init_evtlog_size) + fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + else + fw->init_evtlog_size = + cfg->base_params->max_event_log_size; + fw->init_errlog_ptr = pieces.init_errlog_ptr; + fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; + if (pieces.inst_evtlog_size) + fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + else + fw->inst_evtlog_size = + cfg->base_params->max_event_log_size; + fw->inst_errlog_ptr = pieces.inst_errlog_ptr; + + /* + * figure out the offset of chain noise reset and gain commands + * base on the size of standard phy calibration commands table size + */ + if (fw->ucode_capa.standard_phy_calibration_size > + IWL_MAX_PHY_CALIBRATE_TBL_SIZE) + fw->ucode_capa.standard_phy_calibration_size = + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + complete(&drv->request_firmware_complete); + + drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw); + + if (!drv->op_mode) + goto out_unbind; + + return; + + try_again: + /* try next, if any */ + release_firmware(ucode_raw); + if (iwl_request_firmware(drv, false)) + goto out_unbind; + return; + + err_pci_alloc: + IWL_ERR(drv, "failed to allocate pci memory\n"); + iwl_dealloc_ucode(drv); + release_firmware(ucode_raw); + out_unbind: + complete(&drv->request_firmware_complete); + device_release_driver(trans(drv)->dev); +} + +int iwl_drv_start(struct iwl_shared *shrd, + struct iwl_trans *trans, const struct iwl_cfg *cfg) +{ + struct iwl_drv *drv; + int ret; + + shrd->cfg = cfg; + + drv = kzalloc(sizeof(*drv), GFP_KERNEL); + if (!drv) { + dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv"); + return -ENOMEM; + } + drv->shrd = shrd; + shrd->drv = drv; + + init_completion(&drv->request_firmware_complete); + + ret = iwl_request_firmware(drv, true); + + if (ret) { + dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); + kfree(drv); + shrd->drv = NULL; + } + + return ret; +} + +void iwl_drv_stop(struct iwl_shared *shrd) +{ + struct iwl_drv *drv = shrd->drv; + + wait_for_completion(&drv->request_firmware_complete); + + /* op_mode can be NULL if its start failed */ + if (drv->op_mode) + iwl_op_mode_stop(drv->op_mode); + + iwl_dealloc_ucode(drv); + + kfree(drv); + shrd->drv = NULL; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h new file mode 100644 index 00000000000..3b771c1d909 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -0,0 +1,123 @@ +/****************************************************************************** + * + * 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) 2008 - 2012 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 - 2012 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_drv_h__ +#define __iwl_drv_h__ + +#include "iwl-shared.h" + +/** + * DOC: Driver system flows - drv component + * + * This component implements the system flows such as bus enumeration, bus + * removal. Bus dependent parts of system flows (such as iwl_pci_probe) are in + * bus specific files (transport files). This is the code that is common among + * different buses. + * + * This component is also in charge of managing the several implementations of + * the wifi flows: it will allow to have several fw API implementation. These + * different implementations will differ in the way they implement mac80211's + * handlers too. + + * The init flow wrt to the drv component looks like this: + * 1) The bus specific component is called from module_init + * 2) The bus specific component registers the bus driver + * 3) The bus driver calls the probe function + * 4) The bus specific component configures the bus + * 5) The bus specific component calls to the drv bus agnostic part + * (iwl_drv_start) + * 6) iwl_drv_start fetches the fw ASYNC, iwl_ucode_callback + * 7) iwl_ucode_callback parses the fw file + * 8) iwl_ucode_callback starts the wifi implementation to matches the fw + */ + +/** + * iwl_drv_start - start the drv + * + * @shrd: the shrd area + * @trans_ops: the ops of the transport + * @cfg: device specific constants / virtual functions + * + * TODO: review the parameters given to this function + * + * starts the driver: fetches the firmware. This should be called by bus + * specific system flows implementations. For example, the bus specific probe + * function should do bus related operations only, and then call to this + * function. + */ +int iwl_drv_start(struct iwl_shared *shrd, + struct iwl_trans *trans, const struct iwl_cfg *cfg); + +/** + * iwl_drv_stop - stop the drv + * + * @shrd: the shrd area + * + * TODO: review the parameters given to this function + * + * Stop the driver. This should be called by bus specific system flows + * implementations. For example, the bus specific remove function should first + * call this function and then do the bus related operations only. + */ +void iwl_drv_stop(struct iwl_shared *shrd); + +#endif /* __iwl_drv_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index c1eda9724f4..23cea42b949 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -75,6 +75,7 @@ #include "iwl-agn.h" #include "iwl-eeprom.h" #include "iwl-io.h" +#include "iwl-prph.h" /************************** EEPROM BANDS **************************** * @@ -149,23 +150,27 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ * EEPROM chip, not a single event, so even reads could conflict if they * weren't arbitrated by the semaphore. */ -static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) + +#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ +#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ + +static int iwl_eeprom_acquire_semaphore(struct iwl_trans *trans) { u16 count; int ret; for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { /* Request semaphore */ - iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); /* See if we got it */ - ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, EEPROM_SEM_TIMEOUT); if (ret >= 0) { - IWL_DEBUG_EEPROM(bus, + IWL_DEBUG_EEPROM(trans, "Acquired semaphore after %d tries.\n", count+1); return ret; @@ -175,16 +180,17 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) return ret; } -static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) +static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) { - iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG, + iwl_clear_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); } static int iwl_eeprom_verify_signature(struct iwl_trans *trans) { - u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; + u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & + CSR_EEPROM_GP_VALID_MSK; int ret = 0; IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); @@ -247,46 +253,46 @@ err: } -int iwl_eeprom_check_sku(struct iwl_priv *priv) +int iwl_eeprom_init_hw_params(struct iwl_priv *priv) { struct iwl_shared *shrd = priv->shrd; u16 radio_cfg; - if (!cfg(priv)->sku) { - /* not using sku overwrite */ - cfg(priv)->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE && - !cfg(priv)->ht_params) { - IWL_ERR(priv, "Invalid 11n configuration\n"); - return -EINVAL; - } + hw_params(priv).sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP); + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE && + !cfg(priv)->ht_params) { + IWL_ERR(priv, "Invalid 11n configuration\n"); + return -EINVAL; } - if (!cfg(priv)->sku) { + + if (!hw_params(priv).sku) { IWL_ERR(priv, "Invalid device sku\n"); return -EINVAL; } - IWL_INFO(priv, "Device SKU: 0x%X\n", cfg(priv)->sku); - - if (!cfg(priv)->valid_tx_ant && !cfg(priv)->valid_rx_ant) { - /* not using .cfg overwrite */ - radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); - cfg(priv)->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); - cfg(priv)->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); - if (!cfg(priv)->valid_tx_ant || !cfg(priv)->valid_rx_ant) { - IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", - cfg(priv)->valid_tx_ant, - cfg(priv)->valid_rx_ant); - return -EINVAL; - } - IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", - cfg(priv)->valid_tx_ant, cfg(priv)->valid_rx_ant); + IWL_INFO(priv, "Device SKU: 0x%X\n", hw_params(priv).sku); + + radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG); + + hw_params(priv).valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg); + hw_params(priv).valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); + + /* check overrides (some devices have wrong EEPROM) */ + if (cfg(priv)->valid_tx_ant) + hw_params(priv).valid_tx_ant = cfg(priv)->valid_tx_ant; + if (cfg(priv)->valid_rx_ant) + hw_params(priv).valid_rx_ant = cfg(priv)->valid_rx_ant; + + if (!hw_params(priv).valid_tx_ant || !hw_params(priv).valid_rx_ant) { + IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", + hw_params(priv).valid_tx_ant, + hw_params(priv).valid_rx_ant); + return -EINVAL; } - /* - * for some special cases, - * EEPROM did not reflect the correct antenna setting - * so overwrite the valid tx/rx antenna from .cfg - */ + + IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", + hw_params(priv).valid_tx_ant, hw_params(priv).valid_rx_ant); + return 0; } @@ -303,19 +309,20 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac) * ******************************************************************************/ -static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) +static void iwl_set_otp_access(struct iwl_trans *trans, + enum iwl_access_mode mode) { - iwl_read32(bus, CSR_OTP_GP_REG); + iwl_read32(trans, CSR_OTP_GP_REG); if (mode == IWL_OTP_ACCESS_ABSOLUTE) - iwl_clear_bit(bus, CSR_OTP_GP_REG, + iwl_clear_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_OTP_ACCESS_MODE); else - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_OTP_ACCESS_MODE); } -static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) +static int iwl_get_nvm_type(struct iwl_trans *trans, u32 hw_rev) { u32 otpgp; int nvm_type; @@ -323,7 +330,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) /* OTP only valid for CP/PP and after */ switch (hw_rev & CSR_HW_REV_TYPE_MSK) { case CSR_HW_REV_TYPE_NONE: - IWL_ERR(bus, "Unknown hardware type\n"); + IWL_ERR(trans, "Unknown hardware type\n"); return -ENOENT; case CSR_HW_REV_TYPE_5300: case CSR_HW_REV_TYPE_5350: @@ -332,7 +339,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) nvm_type = NVM_DEVICE_TYPE_EEPROM; break; default: - otpgp = iwl_read32(bus, CSR_OTP_GP_REG); + otpgp = iwl_read32(trans, CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) nvm_type = NVM_DEVICE_TYPE_OTP; else @@ -342,73 +349,74 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) return nvm_type; } -static int iwl_init_otp_access(struct iwl_bus *bus) +static int iwl_init_otp_access(struct iwl_trans *trans) { int ret; /* Enable 40MHz radio clock */ - iwl_write32(bus, CSR_GP_CNTRL, - iwl_read32(bus, CSR_GP_CNTRL) | + iwl_write32(trans, CSR_GP_CNTRL, + iwl_read32(trans, CSR_GP_CNTRL) | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* wait for clock to be ready */ - ret = iwl_poll_bit(bus, CSR_GP_CNTRL, + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) - IWL_ERR(bus, "Time out access OTP\n"); + IWL_ERR(trans, "Time out access OTP\n"); else { - iwl_set_bits_prph(bus, APMG_PS_CTRL_REG, + iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); udelay(5); - iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG, + iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); /* * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ - if (cfg(bus)->base_params->shadow_ram_support) - iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, + if (cfg(trans)->base_params->shadow_ram_support) + iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); } return ret; } -static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) +static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, + __le16 *eeprom_data) { int ret = 0; u32 r; u32 otpgp; - iwl_write32(bus, CSR_EEPROM_REG, + iwl_write32(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(bus, CSR_EEPROM_REG, + ret = iwl_poll_bit(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); if (ret < 0) { - IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); + IWL_ERR(trans, "Time out reading OTP[%d]\n", addr); return ret; } - r = iwl_read32(bus, CSR_EEPROM_REG); + r = iwl_read32(trans, CSR_EEPROM_REG); /* check for ECC errors: */ - otpgp = iwl_read32(bus, CSR_OTP_GP_REG); + otpgp = iwl_read32(trans, CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { /* stop in this case */ /* set the uncorrectable OTP ECC bit for acknowledgement */ - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); - IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); + IWL_ERR(trans, "Uncorrectable OTP ECC error, abort OTP read\n"); return -EINVAL; } if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { /* continue in this case */ /* set the correctable OTP ECC bit for acknowledgement */ - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); - IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); + IWL_ERR(trans, "Correctable OTP ECC error, continue read\n"); } *eeprom_data = cpu_to_le16(r >> 16); return 0; @@ -417,20 +425,20 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) /* * iwl_is_otp_empty: check for empty OTP */ -static bool iwl_is_otp_empty(struct iwl_bus *bus) +static bool iwl_is_otp_empty(struct iwl_trans *trans) { u16 next_link_addr = 0; __le16 link_value; bool is_empty = false; /* locate the beginning of OTP link list */ - if (!iwl_read_otp_word(bus, next_link_addr, &link_value)) { + if (!iwl_read_otp_word(trans, next_link_addr, &link_value)) { if (!link_value) { - IWL_ERR(bus, "OTP is empty\n"); + IWL_ERR(trans, "OTP is empty\n"); is_empty = true; } } else { - IWL_ERR(bus, "Unable to read first block of OTP list.\n"); + IWL_ERR(trans, "Unable to read first block of OTP list.\n"); is_empty = true; } @@ -447,7 +455,7 @@ static bool iwl_is_otp_empty(struct iwl_bus *bus) * we should read and used to configure the device. * only perform this operation if shadow RAM is disabled */ -static int iwl_find_otp_image(struct iwl_bus *bus, +static int iwl_find_otp_image(struct iwl_trans *trans, u16 *validblockaddr) { u16 next_link_addr = 0, valid_addr; @@ -455,10 +463,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus, int usedblocks = 0; /* set addressing mode to absolute to traverse the link list */ - iwl_set_otp_access(bus, IWL_OTP_ACCESS_ABSOLUTE); + iwl_set_otp_access(trans, IWL_OTP_ACCESS_ABSOLUTE); /* checking for empty OTP or error */ - if (iwl_is_otp_empty(bus)) + if (iwl_is_otp_empty(trans)) return -EINVAL; /* @@ -472,9 +480,9 @@ static int iwl_find_otp_image(struct iwl_bus *bus, */ valid_addr = next_link_addr; next_link_addr = le16_to_cpu(link_value) * sizeof(u16); - IWL_DEBUG_EEPROM(bus, "OTP blocks %d addr 0x%x\n", + IWL_DEBUG_EEPROM(trans, "OTP blocks %d addr 0x%x\n", usedblocks, next_link_addr); - if (iwl_read_otp_word(bus, next_link_addr, &link_value)) + if (iwl_read_otp_word(trans, next_link_addr, &link_value)) return -EINVAL; if (!link_value) { /* @@ -489,10 +497,10 @@ static int iwl_find_otp_image(struct iwl_bus *bus, } /* more in the link list, continue */ usedblocks++; - } while (usedblocks <= cfg(bus)->base_params->max_ll_items); + } while (usedblocks <= cfg(trans)->base_params->max_ll_items); /* OTP has no valid blocks */ - IWL_DEBUG_EEPROM(bus, "OTP has no valid blocks\n"); + IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n"); return -EINVAL; } @@ -505,7 +513,7 @@ static int iwl_find_otp_image(struct iwl_bus *bus, * iwl_get_max_txpower_avg - get the highest tx power from all chains. * find the highest tx power from all chains for the channel */ -static s8 iwl_get_max_txpower_avg(struct iwl_cfg *cfg, +static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg, struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element, s8 *max_txpower_in_half_dbm) { @@ -581,7 +589,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv, #define TXP_CHECK_AND_PRINT(x) ((txp->flags & IWL_EEPROM_ENH_TXP_FL_##x) \ ? # x " " : "") -void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) +static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) { struct iwl_shared *shrd = priv->shrd; struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; @@ -652,65 +660,62 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) * * NOTE: This routine uses the non-debug IO access functions. */ -int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) +int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev) { - struct iwl_shared *shrd = priv->shrd; __le16 *e; - u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP); + u32 gp = iwl_read32(trans, CSR_EEPROM_GP); int sz; int ret; u16 addr; u16 validblockaddr = 0; u16 cache_addr = 0; - trans(priv)->nvm_device_type = iwl_get_nvm_type(bus(priv), hw_rev); - if (trans(priv)->nvm_device_type == -ENOENT) + trans->nvm_device_type = iwl_get_nvm_type(trans, hw_rev); + if (trans->nvm_device_type == -ENOENT) return -ENOENT; /* allocate eeprom */ - sz = cfg(priv)->base_params->eeprom_size; - IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); - shrd->eeprom = kzalloc(sz, GFP_KERNEL); - if (!shrd->eeprom) { + sz = cfg(trans)->base_params->eeprom_size; + IWL_DEBUG_EEPROM(trans, "NVM size = %d\n", sz); + trans->shrd->eeprom = kzalloc(sz, GFP_KERNEL); + if (!trans->shrd->eeprom) { ret = -ENOMEM; goto alloc_err; } - e = (__le16 *)shrd->eeprom; - - iwl_apm_init(priv); + e = (__le16 *)trans->shrd->eeprom; - ret = iwl_eeprom_verify_signature(trans(priv)); + ret = iwl_eeprom_verify_signature(trans); if (ret < 0) { - IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); + IWL_ERR(trans, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); ret = -ENOENT; goto err; } /* Make sure driver (instead of uCode) is allowed to read EEPROM */ - ret = iwl_eeprom_acquire_semaphore(bus(priv)); + ret = iwl_eeprom_acquire_semaphore(trans); if (ret < 0) { - IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); + IWL_ERR(trans, "Failed to acquire EEPROM semaphore.\n"); ret = -ENOENT; goto err; } - if (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) { + if (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) { - ret = iwl_init_otp_access(bus(priv)); + ret = iwl_init_otp_access(trans); if (ret) { - IWL_ERR(priv, "Failed to initialize OTP access.\n"); + IWL_ERR(trans, "Failed to initialize OTP access.\n"); ret = -ENOENT; goto done; } - iwl_write32(bus(priv), CSR_EEPROM_GP, - iwl_read32(bus(priv), CSR_EEPROM_GP) & + iwl_write32(trans, CSR_EEPROM_GP, + iwl_read32(trans, CSR_EEPROM_GP) & ~CSR_EEPROM_GP_IF_OWNER_MSK); - iwl_set_bit(bus(priv), CSR_OTP_GP_REG, + iwl_set_bit(trans, CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ - if (!cfg(priv)->base_params->shadow_ram_support) { - if (iwl_find_otp_image(bus(priv), &validblockaddr)) { + if (!cfg(trans)->base_params->shadow_ram_support) { + if (iwl_find_otp_image(trans, &validblockaddr)) { ret = -ENOENT; goto done; } @@ -719,7 +724,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) addr += sizeof(u16)) { __le16 eeprom_data; - ret = iwl_read_otp_word(bus(priv), addr, &eeprom_data); + ret = iwl_read_otp_word(trans, addr, &eeprom_data); if (ret) goto done; e[cache_addr / 2] = eeprom_data; @@ -730,36 +735,35 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) for (addr = 0; addr < sz; addr += sizeof(u16)) { u32 r; - iwl_write32(bus(priv), CSR_EEPROM_REG, + iwl_write32(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG, + ret = iwl_poll_bit(trans, CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); if (ret < 0) { - IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); + IWL_ERR(trans, + "Time out reading EEPROM[%d]\n", addr); goto done; } - r = iwl_read32(bus(priv), CSR_EEPROM_REG); + r = iwl_read32(trans, CSR_EEPROM_REG); e[addr / 2] = cpu_to_le16(r >> 16); } } - IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n", - (trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP) + IWL_DEBUG_EEPROM(trans, "NVM Type: %s, version: 0x%x\n", + (trans->nvm_device_type == NVM_DEVICE_TYPE_OTP) ? "OTP" : "EEPROM", - iwl_eeprom_query16(shrd, EEPROM_VERSION)); + iwl_eeprom_query16(trans->shrd, EEPROM_VERSION)); ret = 0; done: - iwl_eeprom_release_semaphore(bus(priv)); + iwl_eeprom_release_semaphore(trans); err: if (ret) - iwl_eeprom_free(priv->shrd); - /* Reset chip to save power until we load uCode during "up". */ - iwl_apm_stop(priv); + iwl_eeprom_free(trans->shrd); alloc_err: return ret; } @@ -1021,8 +1025,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) * driver need to process addition information * to determine the max channel tx power limits */ - if (cfg(priv)->lib->eeprom_ops.update_enhanced_txpower) - cfg(priv)->lib->eeprom_ops.update_enhanced_txpower(priv); + if (cfg(priv)->lib->eeprom_ops.enhanced_txpower) + iwl_eeprom_enhanced_txpower(priv); return 0; } @@ -1072,7 +1076,7 @@ void iwl_rf_config(struct iwl_priv *priv) /* write radio config values to register */ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(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)); @@ -1084,7 +1088,7 @@ void iwl_rf_config(struct iwl_priv *priv) WARN_ON(1); /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); } diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 9fa937ec35e..e4a75834099 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,6 +67,7 @@ struct iwl_priv; struct iwl_shared; +struct iwl_trans; /* * EEPROM access time values: @@ -301,14 +302,14 @@ extern const u8 iwl_eeprom_band_1[14]; struct iwl_eeprom_ops { const u32 regulatory_bands[7]; - void (*update_enhanced_txpower) (struct iwl_priv *priv); + bool enhanced_txpower; }; -int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev); +int iwl_eeprom_init(struct iwl_trans *trans, u32 hw_rev); void iwl_eeprom_free(struct iwl_shared *shrd); int iwl_eeprom_check_version(struct iwl_priv *priv); -int iwl_eeprom_check_sku(struct iwl_priv *priv); +int iwl_eeprom_init_hw_params(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset); u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset); int iwl_init_channel_map(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 5bede9d7f95..90208094b8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h new file mode 100644 index 00000000000..c924ccb93c8 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * 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) 2008 - 2012 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 - 2012 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_fw_file_h__ +#define __iwl_fw_file_h__ + +#include <linux/netdevice.h> + +/* v1/v2 uCode file layout */ +struct iwl_ucode_header { + __le32 ver; /* major/minor/API/serial */ + union { + struct { + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v1; + struct { + __le32 build; /* build number */ + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v2; + } u; +}; + +/* + * new TLV uCode file layout + * + * The new TLV file format contains TLVs, that each specify + * some piece of data. To facilitate "groups", for example + * different instruction image with different capabilities, + * bundled with the same init image, an alternative mechanism + * is provided: + * When the alternative field is 0, that means that the item + * is always valid. When it is non-zero, then it is only + * valid in conjunction with items of the same alternative, + * in which case the driver (user) selects one alternative + * to use. + */ + +enum iwl_ucode_tlv_type { + IWL_UCODE_TLV_INVALID = 0, /* unused */ + IWL_UCODE_TLV_INST = 1, + IWL_UCODE_TLV_DATA = 2, + IWL_UCODE_TLV_INIT = 3, + IWL_UCODE_TLV_INIT_DATA = 4, + IWL_UCODE_TLV_BOOT = 5, + IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_PAN = 7, + IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, + IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, + IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, + IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, + IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, + IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, + IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, + IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, + IWL_UCODE_TLV_WOWLAN_INST = 16, + IWL_UCODE_TLV_WOWLAN_DATA = 17, + IWL_UCODE_TLV_FLAGS = 18, + IWL_UCODE_TLV_SEC_RT = 19, + IWL_UCODE_TLV_SEC_INIT = 20, + IWL_UCODE_TLV_SEC_WOWLAN = 21, + IWL_UCODE_TLV_DEF_CALIB = 22, + IWL_UCODE_TLV_PHY_SKU = 23, +}; + +struct iwl_ucode_tlv { + __le16 type; /* see above */ + __le16 alternative; /* see comment */ + __le32 length; /* not including type/length fields */ + u8 data[0]; +}; + +#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 + +struct iwl_tlv_ucode_header { + /* + * The TLV style ucode header is distinguished from + * the v1/v2 style header by first four bytes being + * zero, as such is an invalid combination of + * major/minor/API/serial versions. + */ + __le32 zero; + __le32 magic; + u8 human_readable[64]; + __le32 ver; /* major/minor/API/serial */ + __le32 build; + __le64 alternatives; /* bitmask of valid alternatives */ + /* + * The data contained herein has a TLV layout, + * see above for the TLV header and types. + * Note that each TLV is padded to a length + * that is a multiple of 4 for alignment. + */ + u8 data[0]; +}; + +#endif /* __iwl_fw_file_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h new file mode 100644 index 00000000000..8e36bdc1e52 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * 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) 2008 - 2012 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 - 2012 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_fw_h__ +#define __iwl_fw_h__ +#include <linux/types.h> + +/** + * enum iwl_ucode_tlv_flag - ucode API flags + * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously + * was a separate TLV but moved here to save space. + * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, + * treats good CRC threshold as a boolean + * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). + * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. + */ +enum iwl_ucode_tlv_flag { + IWL_UCODE_TLV_FLAGS_PAN = BIT(0), + IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), + IWL_UCODE_TLV_FLAGS_MFP = BIT(2), + IWL_UCODE_TLV_FLAGS_P2P = BIT(3), +}; + +/* The default calibrate table size if not specified by firmware file */ +#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 +#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19 +#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253 + +/** + * enum iwl_ucode_type + * + * The type of ucode. + * + * @IWL_UCODE_REGULAR: Normal runtime ucode + * @IWL_UCODE_INIT: Initial ucode + * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode + */ +enum iwl_ucode_type { + IWL_UCODE_REGULAR, + IWL_UCODE_INIT, + IWL_UCODE_WOWLAN, + IWL_UCODE_TYPE_MAX, +}; + +/* + * enumeration of ucode section. + * This enumeration is used for legacy tlv style (before 16.0 uCode). + */ +enum iwl_ucode_sec { + IWL_UCODE_SECTION_INST, + IWL_UCODE_SECTION_DATA, +}; +/* + * For 16.0 uCode and above, there is no differentiation between sections, + * just an offset to the HW address. + */ +#define IWL_UCODE_SECTION_MAX 4 + +struct iwl_ucode_capabilities { + u32 max_probe_length; + u32 standard_phy_calibration_size; + u32 flags; +}; + +/* one for each uCode image (inst/data, init/runtime/wowlan) */ +struct fw_desc { + dma_addr_t p_addr; /* hardware address */ + void *v_addr; /* software address */ + u32 len; /* size in bytes */ + u32 offset; /* offset in the device */ +}; + +struct fw_img { + struct fw_desc sec[IWL_UCODE_SECTION_MAX]; +}; + +/* uCode version contains 4 values: Major/Minor/API/Serial */ +#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24) +#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16) +#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8) +#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF) + +/** + * struct iwl_fw - variables associated with the firmware + * + * @ucode_ver: ucode version from the ucode file + * @fw_version: firmware version string + * @img: ucode image like ucode_rt, ucode_init, ucode_wowlan. + * @ucode_capa: capabilities parsed from the ucode file. + * @enhance_sensitivity_table: device can do enhanced sensitivity. + * @init_evtlog_ptr: event log offset for init ucode. + * @init_evtlog_size: event log size for init ucode. + * @init_errlog_ptr: error log offfset for init ucode. + * @inst_evtlog_ptr: event log offset for runtime ucode. + * @inst_evtlog_size: event log size for runtime ucode. + * @inst_errlog_ptr: error log offfset for runtime ucode. + */ +struct iwl_fw { + u32 ucode_ver; + + char fw_version[ETHTOOL_BUSINFO_LEN]; + + /* ucode images */ + struct fw_img img[IWL_UCODE_TYPE_MAX]; + + struct iwl_ucode_capabilities ucode_capa; + bool enhance_sensitivity_table; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; + + u64 default_calib[IWL_UCODE_TYPE_MAX]; + u32 phy_config; + + bool mvm_fw; +}; + +#endif /* __iwl_fw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index d57ea6484bb..081dd34d238 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * @@ -34,41 +34,41 @@ #define IWL_POLL_INTERVAL 10 /* microseconds */ -static inline void __iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) +static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { - iwl_write32(bus, reg, iwl_read32(bus, reg) | mask); + iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); } -static inline void __iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) +static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { - iwl_write32(bus, reg, iwl_read32(bus, reg) & ~mask); + iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); } -void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - __iwl_set_bit(bus, reg, mask); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + __iwl_set_bit(trans, reg, mask); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - __iwl_clear_bit(bus, reg, mask); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + __iwl_clear_bit(trans, reg, mask); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -int iwl_poll_bit(struct iwl_bus *bus, u32 addr, +int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { int t = 0; do { - if ((iwl_read32(bus, addr) & mask) == (bits & mask)) + if ((iwl_read32(trans, addr) & mask) == (bits & mask)) return t; udelay(IWL_POLL_INTERVAL); t += IWL_POLL_INTERVAL; @@ -77,14 +77,15 @@ int iwl_poll_bit(struct iwl_bus *bus, u32 addr, return -ETIMEDOUT; } -int iwl_grab_nic_access_silent(struct iwl_bus *bus) +int iwl_grab_nic_access_silent(struct iwl_trans *trans) { int ret; - lockdep_assert_held(&bus->reg_lock); + lockdep_assert_held(&trans->reg_lock); /* this bit wakes up the NIC */ - __iwl_set_bit(bus, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + __iwl_set_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* * These bits say the device is running, and should keep running for @@ -105,70 +106,78 @@ int iwl_grab_nic_access_silent(struct iwl_bus *bus) * 5000 series and later (including 1000 series) have non-volatile SRAM, * and do not save/restore SRAM when power cycling. */ - ret = iwl_poll_bit(bus, CSR_GP_CNTRL, + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (ret < 0) { - iwl_write32(bus, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); return -EIO; } return 0; } -int iwl_grab_nic_access(struct iwl_bus *bus) +bool iwl_grab_nic_access(struct iwl_trans *trans) { - int ret = iwl_grab_nic_access_silent(bus); - if (ret) { - u32 val = iwl_read32(bus, CSR_GP_CNTRL); - IWL_ERR(bus, - "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); + int ret = iwl_grab_nic_access_silent(trans); + if (unlikely(ret)) { + u32 val = iwl_read32(trans, CSR_GP_CNTRL); + WARN_ONCE(1, "Timeout waiting for hardware access " + "(CSR_GP_CNTRL 0x%08x)\n", val); + return false; } - return ret; + return true; } -void iwl_release_nic_access(struct iwl_bus *bus) +void iwl_release_nic_access(struct iwl_trans *trans) { - lockdep_assert_held(&bus->reg_lock); - __iwl_clear_bit(bus, CSR_GP_CNTRL, + lockdep_assert_held(&trans->reg_lock); + __iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + /* + * Above we read the CSR_GP_CNTRL register, which will flush + * any previous writes, but we need the write that clears the + * MAC_ACCESS_REQ bit to be performed before any other writes + * scheduled on different CPUs (after we drop reg_lock). + */ + mmiowb(); } -u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg) +u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { u32 value; unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - value = iwl_read32(bus, reg); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + value = iwl_read32(trans, reg); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); return value; } -void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value) +void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - iwl_write32(bus, reg, value); - iwl_release_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + iwl_write32(trans, reg, value); + iwl_release_nic_access(trans); } - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, +int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout) { int t = 0; do { - if ((iwl_read_direct32(bus, addr) & mask) == mask) + if ((iwl_read_direct32(trans, addr) & mask) == mask) return t; udelay(IWL_POLL_INTERVAL); t += IWL_POLL_INTERVAL; @@ -177,135 +186,132 @@ int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, return -ETIMEDOUT; } -static inline u32 __iwl_read_prph(struct iwl_bus *bus, u32 reg) +static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) { - iwl_write32(bus, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); - rmb(); - return iwl_read32(bus, HBUS_TARG_PRPH_RDAT); + iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); } -static inline void __iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) +static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { - iwl_write32(bus, HBUS_TARG_PRPH_WADDR, + iwl_write32(trans, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24))); - wmb(); - iwl_write32(bus, HBUS_TARG_PRPH_WDAT, val); + iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); } -u32 iwl_read_prph(struct iwl_bus *bus, u32 reg) +u32 iwl_read_prph(struct iwl_trans *trans, u32 reg) { unsigned long flags; u32 val; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - val = __iwl_read_prph(bus, reg); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + val = __iwl_read_prph(trans, reg); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); return val; } -void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) +void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - __iwl_write_prph(bus, addr, val); - iwl_release_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + __iwl_write_prph(trans, addr, val); + iwl_release_nic_access(trans); } - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - __iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + __iwl_write_prph(trans, reg, + __iwl_read_prph(trans, reg) | mask); + iwl_release_nic_access(trans); + } + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, +void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - __iwl_write_prph(bus, reg, - (__iwl_read_prph(bus, reg) & mask) | bits); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + __iwl_write_prph(trans, reg, + (__iwl_read_prph(trans, reg) & mask) | bits); + iwl_release_nic_access(trans); + } + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; u32 val; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - val = __iwl_read_prph(bus, reg); - __iwl_write_prph(bus, reg, (val & ~mask)); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + val = __iwl_read_prph(trans, reg); + __iwl_write_prph(trans, reg, (val & ~mask)); + iwl_release_nic_access(trans); + } + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, +void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) { unsigned long flags; int offs; u32 *vals = buf; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - - iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr); - rmb(); - - for (offs = 0; offs < words; offs++) - vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT); - - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); + for (offs = 0; offs < words; offs++) + vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + iwl_release_nic_access(trans); + } + spin_unlock_irqrestore(&trans->reg_lock, flags); } -u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr) +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) { u32 value; - _iwl_read_targ_mem_words(bus, addr, &value, 1); + _iwl_read_targ_mem_words(trans, addr, &value, 1); return value; } -int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, +int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) { unsigned long flags; int offs, result = 0; u32 *vals = buf; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr); - wmb(); - + spin_lock_irqsave(&trans->reg_lock, flags); + if (likely(iwl_grab_nic_access(trans))) { + iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); for (offs = 0; offs < words; offs++) - iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]); - iwl_release_nic_access(bus); + iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); + iwl_release_nic_access(trans); } else result = -EBUSY; - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); return result; } -int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val) +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) { - return _iwl_write_targ_mem_words(bus, addr, &val, 1); + return _iwl_write_targ_mem_words(trans, addr, &val, 1); } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index aae2eeb331a..09b856768f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * @@ -31,63 +31,63 @@ #include "iwl-devtrace.h" #include "iwl-shared.h" -#include "iwl-bus.h" +#include "iwl-trans.h" -static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val) +static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) { - trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val); - bus_write8(bus, ofs, val); + trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); + iwl_trans_write8(trans, ofs, val); } -static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val) +static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) { - trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val); - bus_write32(bus, ofs, val); + trace_iwlwifi_dev_iowrite32(trans->dev, ofs, val); + iwl_trans_write32(trans, ofs, val); } -static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs) +static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) { - u32 val = bus_read32(bus, ofs); - trace_iwlwifi_dev_ioread32(priv(bus), ofs, val); + u32 val = iwl_trans_read32(trans, ofs); + trace_iwlwifi_dev_ioread32(trans->dev, ofs, val); return val; } -void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask); -void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask); +void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); -int iwl_poll_bit(struct iwl_bus *bus, u32 addr, +int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout); -int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, +int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout); -int iwl_grab_nic_access_silent(struct iwl_bus *bus); -int iwl_grab_nic_access(struct iwl_bus *bus); -void iwl_release_nic_access(struct iwl_bus *bus); +int iwl_grab_nic_access_silent(struct iwl_trans *trans); +bool iwl_grab_nic_access(struct iwl_trans *trans); +void iwl_release_nic_access(struct iwl_trans *trans); -u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg); -void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value); +u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); +void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); -u32 iwl_read_prph(struct iwl_bus *bus, u32 reg); -void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val); -void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); -void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, +u32 iwl_read_prph(struct iwl_trans *trans, u32 reg); +void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val); +void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask); -void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); +void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); -void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, +void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -#define iwl_read_targ_mem_words(bus, addr, buf, bufsize) \ +#define iwl_read_targ_mem_words(trans, addr, buf, bufsize) \ do { \ BUILD_BUG_ON((bufsize) % sizeof(u32)); \ - _iwl_read_targ_mem_words(bus, addr, buf, \ + _iwl_read_targ_mem_words(trans, addr, buf, \ (bufsize) / sizeof(u32));\ } while (0) -int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, +int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr); -int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val); +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 14dcbfcdc0f..1993a2b7ae6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 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 @@ -71,7 +71,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { /* Set led register off */ void iwlagn_led_enable(struct iwl_priv *priv) { - iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); + iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); } /* @@ -107,11 +107,12 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) }; u32 reg; - reg = iwl_read32(bus(priv), CSR_LED_REG); + reg = iwl_read32(trans(priv), CSR_LED_REG); if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) - iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); + iwl_write32(trans(priv), CSR_LED_REG, + reg & CSR_LED_BSM_CTRL_MSK); - return iwl_trans_send_cmd(trans(priv), &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } /* Set led pattern command */ @@ -125,7 +126,7 @@ static int iwl_led_cmd(struct iwl_priv *priv, }; int ret; - if (!test_bit(STATUS_READY, &priv->shrd->status)) + if (!test_bit(STATUS_READY, &priv->status)) return -EBUSY; if (priv->blink_on == on && priv->blink_off == off) @@ -177,6 +178,10 @@ void iwl_leds_init(struct iwl_priv *priv) int mode = iwlagn_mod_params.led_mode; int ret; + if (mode == IWL_LED_DISABLE) { + IWL_INFO(priv, "Led disabled\n"); + return; + } if (mode == IWL_LED_DEFAULT) mode = cfg(priv)->led_mode; @@ -202,7 +207,7 @@ void iwl_leds_init(struct iwl_priv *priv) break; } - ret = led_classdev_register(bus(priv)->dev, &priv->led); + ret = led_classdev_register(trans(priv)->dev, &priv->led); if (ret) { kfree(priv->led.name); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 2550b3c7dcb..b02a853103d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index f980e574e1f..b6805f8e9a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -35,7 +35,6 @@ #include <linux/sched.h> #include <linux/skbuff.h> #include <linux/netdevice.h> -#include <linux/firmware.h> #include <linux/etherdevice.h> #include <linux/if_arp.h> @@ -44,15 +43,14 @@ #include <asm/div64.h> #include "iwl-eeprom.h" -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" #include "iwl-agn-calib.h" #include "iwl-agn.h" #include "iwl-shared.h" -#include "iwl-bus.h" #include "iwl-trans.h" +#include "iwl-op-mode.h" /***************************************************************************** * @@ -136,7 +134,7 @@ iwlagn_iface_combinations_p2p[] = { * other mac80211 functions grouped here. */ int iwlagn_mac_setup_register(struct iwl_priv *priv, - struct iwlagn_ucode_capabilities *capa) + const struct iwl_ucode_capabilities *capa) { int ret; struct ieee80211_hw *hw = priv->hw; @@ -161,11 +159,14 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; - if (cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE) + if (hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; +#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP + /* enable 11w if the uCode advertise */ if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) +#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ hw->flags |= IEEE80211_HW_MFP_CAPABLE; hw->sta_data_size = sizeof(struct iwl_station_priv); @@ -195,8 +196,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; - if (trans(priv)->ucode_wowlan.code.len && - device_can_wakeup(bus(priv)->dev)) { + if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && + trans(priv)->ops->wowlan_suspend && + device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_EAP_IDENTITY_REQ | @@ -234,7 +236,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; - hw->wiphy->hw_version = bus_get_hw_id(bus(priv)); + hw->wiphy->hw_version = trans(priv)->hw_id; iwl_leds_init(priv); @@ -262,9 +264,9 @@ static int __iwl_up(struct iwl_priv *priv) struct iwl_rxon_context *ctx; int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); return -EIO; } @@ -277,13 +279,13 @@ static int __iwl_up(struct iwl_priv *priv) } } - ret = iwl_run_init_ucode(trans(priv)); + ret = iwl_run_init_ucode(priv); if (ret) { IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); goto error; } - ret = iwl_load_ucode_wait_alive(trans(priv), IWL_UCODE_REGULAR); + ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); if (ret) { IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); goto error; @@ -295,9 +297,9 @@ static int __iwl_up(struct iwl_priv *priv) return 0; error: - set_bit(STATUS_EXIT_PENDING, &priv->shrd->status); - __iwl_down(priv); - clear_bit(STATUS_EXIT_PENDING, &priv->shrd->status); + set_bit(STATUS_EXIT_PENDING, &priv->status); + iwl_down(priv); + clear_bit(STATUS_EXIT_PENDING, &priv->status); IWL_ERR(priv, "Unable to initialize device.\n"); return ret; @@ -305,22 +307,22 @@ static int __iwl_up(struct iwl_priv *priv) static int iwlagn_mac_start(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int ret; IWL_DEBUG_MAC80211(priv, "enter\n"); /* we should be verifying the device is ready to be opened */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); ret = __iwl_up(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); if (ret) return ret; IWL_DEBUG_INFO(priv, "Start UP work done.\n"); /* Now we should be done, and the READY bit should be set. */ - if (WARN_ON(!test_bit(STATUS_READY, &priv->shrd->status))) + if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) ret = -EIO; iwlagn_led_enable(priv); @@ -332,7 +334,7 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) static void iwlagn_mac_stop(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -341,14 +343,19 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) priv->is_open = 0; + mutex_lock(&priv->mutex); iwl_down(priv); + mutex_unlock(&priv->mutex); + + iwl_cancel_deferred_work(priv); - flush_workqueue(priv->shrd->workqueue); + flush_workqueue(priv->workqueue); /* User space software may expect getting rfkill changes - * even if interface is down */ - iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); - iwl_enable_rfkill_int(priv); + * even if interface is down, trans->down will leave the RF + * kill interrupt enabled + */ + iwl_trans_stop_hw(trans(priv)); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -357,13 +364,13 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_gtk_rekey_data *data) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); if (iwlagn_mod_params.sw_crypto) return; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (priv->contexts[IWL_RXON_CTX_BSS].vif != vif) goto out; @@ -375,7 +382,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, priv->have_rekey_data = true; out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -384,7 +391,7 @@ static void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, static int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int ret; @@ -392,7 +399,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, return -EINVAL; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); /* Don't attempt WoWLAN when not associated, tear down instead. */ if (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION || @@ -401,24 +408,22 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, goto out; } - ret = iwlagn_suspend(priv, hw, wowlan); + ret = iwlagn_suspend(priv, wowlan); if (ret) goto error; - device_set_wakeup_enable(bus(priv)->dev, true); + device_set_wakeup_enable(trans(priv)->dev, true); - /* Now let the ucode operate on its own */ - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); + iwl_trans_wowlan_suspend(trans(priv)); goto out; error: - priv->shrd->wowlan = false; + priv->wowlan = false; iwlagn_prepare_restart(priv); ieee80211_restart_hw(priv->hw); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -426,42 +431,45 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, static int iwlagn_mac_resume(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct ieee80211_vif *vif; unsigned long flags; u32 base, status = 0xffffffff; int ret = -EIO; + const struct fw_img *img; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); base = priv->shrd->device_pointers.error_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - spin_lock_irqsave(&bus(priv)->reg_lock, flags); - ret = iwl_grab_nic_access_silent(bus(priv)); - if (ret == 0) { - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); - status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - iwl_release_nic_access(bus(priv)); + spin_lock_irqsave(&trans(priv)->reg_lock, flags); + ret = iwl_grab_nic_access_silent(trans(priv)); + if (likely(ret == 0)) { + iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); + status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + iwl_release_nic_access(trans(priv)); } - spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); + spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); #ifdef CONFIG_IWLWIFI_DEBUGFS if (ret == 0) { - struct iwl_trans *trans = trans(priv); - if (!priv->wowlan_sram) + img = &(priv->fw->img[IWL_UCODE_WOWLAN]); + if (!priv->wowlan_sram) { priv->wowlan_sram = - kzalloc(trans->ucode_wowlan.data.len, + kzalloc(img->sec[IWL_UCODE_SECTION_DATA].len, GFP_KERNEL); + } if (priv->wowlan_sram) _iwl_read_targ_mem_words( - bus(priv), 0x800000, priv->wowlan_sram, - trans->ucode_wowlan.data.len / 4); + trans(priv), 0x800000, + priv->wowlan_sram, + img->sec[IWL_UCODE_SECTION_DATA].len / 4); } #endif } @@ -469,9 +477,9 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) /* we'll clear ctx->vif during iwlagn_prepare_restart() */ vif = ctx->vif; - priv->shrd->wowlan = false; + priv->wowlan = false; - device_set_wakeup_enable(bus(priv)->dev, false); + device_set_wakeup_enable(trans(priv)->dev, false); iwlagn_prepare_restart(priv); @@ -479,7 +487,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) iwl_connection_init_rx_config(priv, ctx); iwlagn_set_rxon_chain(priv, ctx); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); ieee80211_resume_disconnect(vif); @@ -491,7 +499,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); @@ -506,7 +514,7 @@ static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); iwl_update_tkip_key(priv, vif, keyconf, sta, iv32, phase1key); } @@ -516,7 +524,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_sta *sta, struct ieee80211_key_conf *key) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *ctx = vif_priv->ctx; int ret; @@ -557,7 +565,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (cmd == DISABLE_KEY && key->hw_key_idx == WEP_INVALID_OFFSET) return 0; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, 100); BUILD_BUG_ON(WEP_INVALID_OFFSET == IWLAGN_HW_KEY_DEFAULT); @@ -608,7 +616,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ret = -EINVAL; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -620,18 +628,18 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int ret = -EINVAL; struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n", sta->addr, tid); - if (!(cfg(priv)->sku & EEPROM_SKU_CAP_11N_ENABLE)) + if (!(hw_params(priv).sku & EEPROM_SKU_CAP_11N_ENABLE)) return -EACCES; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); switch (action) { case IEEE80211_AMPDU_RX_START: @@ -643,8 +651,6 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: IWL_DEBUG_HT(priv, "stop Rx\n"); ret = iwl_sta_rx_agg_stop(priv, sta, tid); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - ret = 0; break; case IEEE80211_AMPDU_TX_START: if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) @@ -660,10 +666,8 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n", priv->agg_tids_count); } - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) - ret = 0; - if (!priv->agg_tids_count && cfg(priv)->ht_params && - cfg(priv)->ht_params->use_rts_for_aggregation) { + if (!priv->agg_tids_count && + hw_params(priv).use_rts_for_aggregation) { /* * switch off RTS/CTS if it was previously enabled */ @@ -677,7 +681,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwlagn_tx_agg_oper(priv, vif, sta, tid, buf_size); break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; } @@ -686,16 +690,13 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; bool is_ap = vif->type == NL80211_IFTYPE_STATION; - int ret = 0; + int ret; u8 sta_id; - IWL_DEBUG_MAC80211(priv, "received request to add station %pM\n", - sta->addr); - mutex_lock(&priv->shrd->mutex); IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", sta->addr); sta_priv->sta_id = IWL_INVALID_STATION; @@ -710,17 +711,119 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ - goto out; + return ret; } sta_priv->sta_id = sta_id; - /* Initialize rate scaling */ - IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", - sta->addr); - iwl_rs_rate_init(priv, sta, sta_id); - out: - mutex_unlock(&priv->shrd->mutex); + return 0; +} + +static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + int ret; + + IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", sta->addr); + + if (vif->type == NL80211_IFTYPE_STATION) { + /* + * Station will be removed from device when the RXON + * is set to unassociated -- just deactivate it here + * to avoid re-programming it. + */ + ret = 0; + iwl_deactivate_station(priv, sta_priv->sta_id, sta->addr); + } else { + ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); + if (ret) + IWL_DEBUG_QUIET_RFKILL(priv, + "Error removing station %pM\n", sta->addr); + } + return ret; +} + +static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + enum { + NONE, ADD, REMOVE, HT_RATE_INIT, ADD_RATE_INIT, + } op = NONE; + int ret; + + IWL_DEBUG_MAC80211(priv, "station %pM state change %d->%d\n", + sta->addr, old_state, new_state); + + mutex_lock(&priv->mutex); + if (vif->type == NL80211_IFTYPE_STATION) { + if (old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + op = ADD; + else if (old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST) + op = REMOVE; + else if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) + op = HT_RATE_INIT; + } else { + if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) + op = ADD_RATE_INIT; + else if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) + op = REMOVE; + } + + switch (op) { + case ADD: + ret = iwlagn_mac_sta_add(hw, vif, sta); + break; + case REMOVE: + ret = iwlagn_mac_sta_remove(hw, vif, sta); + break; + case ADD_RATE_INIT: + ret = iwlagn_mac_sta_add(hw, vif, sta); + if (ret) + break; + /* Initialize rate scaling */ + IWL_DEBUG_INFO(priv, + "Initializing rate scaling for station %pM\n", + sta->addr); + iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); + ret = 0; + break; + case HT_RATE_INIT: + /* Initialize rate scaling */ + ret = iwl_sta_update_ht(priv, vif_priv->ctx, sta); + if (ret) + break; + IWL_DEBUG_INFO(priv, + "Initializing rate scaling for station %pM\n", + sta->addr); + iwl_rs_rate_init(priv, sta, iwl_sta_id(sta)); + ret = 0; + break; + default: + ret = 0; + break; + } + + /* + * mac80211 might WARN if we fail, but due the way we + * (badly) handle hard rfkill, we might fail here + */ + if (iwl_is_rfkill(priv)) + ret = 0; + + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return ret; @@ -729,7 +832,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); const struct iwl_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = ch_switch->channel; @@ -747,14 +850,14 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (iwl_is_rfkill(priv->shrd)) + if (iwl_is_rfkill(priv)) goto out; - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status) || - test_bit(STATUS_SCANNING, &priv->shrd->status) || - test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status)) + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status) || + test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) goto out; if (!iwl_is_associated_ctx(ctx)) @@ -773,8 +876,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, goto out; } - spin_lock_irq(&priv->shrd->lock); - priv->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ @@ -791,23 +892,21 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, iwl_set_rxon_ht(priv, ht_conf); iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); - spin_unlock_irq(&priv->shrd->lock); - iwl_set_rate(priv); /* * at this point, staging_rxon has the * configuration for channel switch */ - set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); + set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); priv->switch_channel = cpu_to_le16(ch); if (cfg(priv)->lib->set_channel_switch(priv, ch_switch)) { - clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status); + clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); priv->switch_channel = 0; ieee80211_chswitch_done(ctx->vif, false); } out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -816,7 +915,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, u64 multicast) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); __le32 filter_or = 0, filter_nand = 0; struct iwl_rxon_context *ctx; @@ -837,7 +936,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, #undef CHK - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); for_each_context(priv, ctx) { ctx->staging.filter_flags &= ~filter_nand; @@ -849,7 +948,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, */ } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); /* * Receiving all multicast frames is always enabled by the @@ -863,16 +962,16 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); - if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) { + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n"); goto done; } - if (iwl_is_rfkill(priv->shrd)) { + if (iwl_is_rfkill(priv)) { IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n"); goto done; } @@ -891,7 +990,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); iwl_trans_wait_tx_queue_empty(trans(priv)); done: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -900,7 +999,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, enum nl80211_channel_type channel_type, int duration) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN]; int err = 0; @@ -911,9 +1010,9 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, return -EOPNOTSUPP; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_HW, &priv->status)) { err = -EBUSY; goto out; } @@ -982,7 +1081,7 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, iwlagn_disable_roc(priv); out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return err; @@ -990,108 +1089,28 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN))) return -EOPNOTSUPP; IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, priv->hw_roc_duration); iwlagn_disable_roc(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; } -static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - struct iwl_rxon_context *ctx = vif_priv->ctx; - int ret; - u8 sta_id; - - if (ctx->ctxid != IWL_RXON_CTX_PAN) - return 0; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); - - if (iwl_is_associated_ctx(ctx)) { - ret = 0; - goto out; - } - - if (ctx->preauth_bssid || test_bit(STATUS_SCAN_HW, - &priv->shrd->status)) { - ret = -EBUSY; - goto out; - } - - ret = iwl_add_station_common(priv, ctx, bssid, true, NULL, &sta_id); - if (ret) - goto out; - - if (WARN_ON(sta_id != ctx->ap_sta_id)) { - ret = -EIO; - goto out_remove_sta; - } - - memcpy(ctx->bssid, bssid, ETH_ALEN); - ctx->preauth_bssid = true; - - ret = iwlagn_commit_rxon(priv, ctx); - - if (ret == 0) - goto out; - - out_remove_sta: - iwl_remove_station(priv, sta_id, bssid); - out: - mutex_unlock(&priv->shrd->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); - - return ret; -} - -static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - const u8 *bssid, - enum ieee80211_tx_sync_type type) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; - struct iwl_rxon_context *ctx = vif_priv->ctx; - - if (ctx->ctxid != IWL_RXON_CTX_PAN) - return; - - IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); - - if (iwl_is_associated_ctx(ctx)) - goto out; - - iwl_remove_station(priv, ctx->ap_sta_id, bssid); - ctx->preauth_bssid = false; - /* no need to commit */ - out: - mutex_unlock(&priv->shrd->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); -} - static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, enum ieee80211_rssi_event rssi_event) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) { @@ -1106,16 +1125,16 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, "ignoring RSSI callback\n"); } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); } static int iwlagn_mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - queue_work(priv->shrd->workqueue, &priv->beacon_update); + queue_work(priv->workqueue, &priv->beacon_update); return 0; } @@ -1124,10 +1143,9 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *ctx = vif_priv->ctx; - unsigned long flags; int q; if (WARN_ON(!ctx)) @@ -1135,7 +1153,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); - if (!iwl_is_ready_rf(priv->shrd)) { + if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); return -EIO; } @@ -1147,7 +1165,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, q = AC_NUM - 1 - queue; - spin_lock_irqsave(&priv->shrd->lock, flags); + mutex_lock(&priv->mutex); ctx->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); @@ -1159,7 +1177,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; - spin_unlock_irqrestore(&priv->shrd->lock, flags); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return 0; @@ -1167,7 +1185,7 @@ static int iwlagn_mac_conf_tx(struct ieee80211_hw *hw, static int iwlagn_mac_tx_last_beacon(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); return priv->ibss_manager == IWL_IBSS_MANAGER; } @@ -1187,7 +1205,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, struct ieee80211_vif *vif = ctx->vif; int err; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* * This variable will be correct only when there's just @@ -1221,7 +1239,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_rxon_context *tmp, *ctx = NULL; int err; @@ -1232,11 +1250,11 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, cancel_delayed_work_sync(&priv->hw_roc_disable_work); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwlagn_disable_roc(priv); - if (!iwl_is_ready_rf(priv->shrd)) { + if (!iwl_is_ready_rf(priv)) { IWL_WARN(priv, "Try to add interface when device not ready\n"); err = -EINVAL; goto out; @@ -1279,7 +1297,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, ctx->vif = NULL; priv->iw_mode = NL80211_IFTYPE_STATION; out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return err; @@ -1291,7 +1309,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, { struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (priv->scan_vif == vif) { iwl_scan_cancel_timeout(priv, 200); @@ -1318,12 +1336,12 @@ static void iwl_teardown_interface(struct iwl_priv *priv, static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); IWL_DEBUG_MAC80211(priv, "enter\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (WARN_ON(ctx->vif != vif)) { struct iwl_rxon_context *tmp; @@ -1336,7 +1354,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw, iwl_teardown_interface(priv, vif, false); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -1346,7 +1364,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_context *tmp; @@ -1358,9 +1376,9 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, newtype = ieee80211_iftype_p2p(newtype, newp2p); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); - if (!ctx->vif || !iwl_is_ready_rf(priv->shrd)) { + if (!ctx->vif || !iwl_is_ready_rf(priv)) { /* * Huh? But wait ... this can maybe happen when * we're in the middle of a firmware restart! @@ -1422,7 +1440,7 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw, err = 0; out: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); return err; @@ -1432,7 +1450,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int ret; IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -1440,7 +1458,7 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, if (req->n_channels == 0) return -EINVAL; - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); /* * If an internal scan is in progress, just set @@ -1469,47 +1487,20 @@ static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "leave\n"); - mutex_unlock(&priv->shrd->mutex); - - return ret; -} - -static int iwlagn_mac_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct iwl_priv *priv = hw->priv; - struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; - int ret; - - IWL_DEBUG_MAC80211(priv, "enter: received request to remove " - "station %pM\n", sta->addr); - mutex_lock(&priv->shrd->mutex); - IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", - sta->addr); - ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr); - if (ret) - IWL_DEBUG_QUIET_RFKILL(priv, "Error removing station %pM\n", - sta->addr); - mutex_unlock(&priv->shrd->mutex); - IWL_DEBUG_MAC80211(priv, "leave\n"); + mutex_unlock(&priv->mutex); return ret; } static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) { - unsigned long flags; - - spin_lock_irqsave(&priv->shrd->sta_lock, flags); - priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = 0; - priv->stations[sta_id].sta.sleep_tx_count = 0; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); + struct iwl_addsta_cmd cmd = { + .mode = STA_CONTROL_MODIFY_MSK, + .station_flags_msk = STA_FLG_PWR_SAVE_MSK, + .sta.sta_id = sta_id, + }; + iwl_send_add_sta(priv, &cmd, CMD_ASYNC); } static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, @@ -1517,7 +1508,7 @@ static void iwlagn_mac_sta_notify(struct ieee80211_hw *hw, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; int sta_id; @@ -1566,8 +1557,7 @@ struct ieee80211_ops iwlagn_hw_ops = { .ampdu_action = iwlagn_mac_ampdu_action, .hw_scan = iwlagn_mac_hw_scan, .sta_notify = iwlagn_mac_sta_notify, - .sta_add = iwlagn_mac_sta_add, - .sta_remove = iwlagn_mac_sta_remove, + .sta_state = iwlagn_mac_sta_state, .channel_switch = iwlagn_mac_channel_switch, .flush = iwlagn_mac_flush, .tx_last_beacon = iwlagn_mac_tx_last_beacon, @@ -1576,8 +1566,6 @@ struct ieee80211_ops iwlagn_hw_ops = { .rssi_callback = iwlagn_mac_rssi_callback, CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) - .tx_sync = iwlagn_mac_tx_sync, - .finish_tx_sync = iwlagn_mac_finish_tx_sync, .set_tim = iwlagn_mac_set_tim, }; @@ -1585,15 +1573,18 @@ struct ieee80211_ops iwlagn_hw_ops = { struct ieee80211_hw *iwl_alloc_all(void) { struct iwl_priv *priv; + struct iwl_op_mode *op_mode; /* mac80211 allocates memory for this device instance, including * space for this driver's private structure */ struct ieee80211_hw *hw; - hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); + hw = ieee80211_alloc_hw(sizeof(struct iwl_priv) + + sizeof(struct iwl_op_mode), &iwlagn_hw_ops); if (!hw) goto out; - priv = hw->priv; + op_mode = hw->priv; + priv = IWL_OP_MODE_GET_DVM(op_mode); priv->hw = hw; out: diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c new file mode 100644 index 00000000000..88dc4a0f96b --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -0,0 +1,157 @@ +/****************************************************************************** + * + * 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 - 2012 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 - 2012 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/sched.h> + +#include "iwl-notif-wait.h" + + +void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) +{ + spin_lock_init(¬if_wait->notif_wait_lock); + INIT_LIST_HEAD(¬if_wait->notif_waits); + init_waitqueue_head(¬if_wait->notif_waitq); +} + +void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt) +{ + if (!list_empty(¬if_wait->notif_waits)) { + struct iwl_notification_wait *w; + + spin_lock(¬if_wait->notif_wait_lock); + list_for_each_entry(w, ¬if_wait->notif_waits, list) { + if (w->cmd != pkt->hdr.cmd) + continue; + w->triggered = true; + if (w->fn) + w->fn(notif_wait, pkt, w->fn_data); + } + spin_unlock(¬if_wait->notif_wait_lock); + + wake_up_all(¬if_wait->notif_waitq); + } +} + +void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) +{ + unsigned long flags; + struct iwl_notification_wait *wait_entry; + + spin_lock_irqsave(¬if_wait->notif_wait_lock, flags); + list_for_each_entry(wait_entry, ¬if_wait->notif_waits, list) + wait_entry->aborted = true; + spin_unlock_irqrestore(¬if_wait->notif_wait_lock, flags); + + wake_up_all(¬if_wait->notif_waitq); +} + + +void +iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, + struct iwl_notification_wait *wait_entry, + u8 cmd, + void (*fn)(struct iwl_notif_wait_data *notif_wait, + struct iwl_rx_packet *pkt, void *data), + void *fn_data) +{ + wait_entry->fn = fn; + wait_entry->fn_data = fn_data; + wait_entry->cmd = cmd; + wait_entry->triggered = false; + wait_entry->aborted = false; + + spin_lock_bh(¬if_wait->notif_wait_lock); + list_add(&wait_entry->list, ¬if_wait->notif_waits); + spin_unlock_bh(¬if_wait->notif_wait_lock); +} + +int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, + struct iwl_notification_wait *wait_entry, + unsigned long timeout) +{ + int ret; + + ret = wait_event_timeout(notif_wait->notif_waitq, + wait_entry->triggered || wait_entry->aborted, + timeout); + + spin_lock_bh(¬if_wait->notif_wait_lock); + list_del(&wait_entry->list); + spin_unlock_bh(¬if_wait->notif_wait_lock); + + if (wait_entry->aborted) + return -EIO; + + /* return value is always >= 0 */ + if (ret <= 0) + return -ETIMEDOUT; + return 0; +} + +void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, + struct iwl_notification_wait *wait_entry) +{ + spin_lock_bh(¬if_wait->notif_wait_lock); + list_del(&wait_entry->list); + spin_unlock_bh(¬if_wait->notif_wait_lock); +} diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index 18501101a53..5e8af957aa7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,6 @@ * 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 @@ -58,17 +57,73 @@ * 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_notif_wait_h__ +#define __iwl_notif_wait_h__ + +#include <linux/wait.h> + +#include "iwl-trans.h" + +struct iwl_notif_wait_data { + struct list_head notif_waits; + spinlock_t notif_wait_lock; + wait_queue_head_t notif_waitq; +}; + +/** + * struct iwl_notification_wait - notification wait entry + * @list: list head for global list + * @fn: function called with the notification + * @cmd: command ID + * + * This structure is not used directly, to wait for a + * notification declare it on the stack, and call + * iwlagn_init_notification_wait() with appropriate + * parameters. Then do whatever will cause the ucode + * to notify the driver, and to wait for that then + * call iwlagn_wait_notification(). + * + * Each notification is one-shot. If at some point we + * need to support multi-shot notifications (which + * can't be allocated on the stack) we need to modify + * the code for them. + */ +struct iwl_notification_wait { + struct list_head list; + + void (*fn)(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt, void *data); + void *fn_data; + + u8 cmd; + bool triggered, aborted; +}; + + +/* caller functions */ +void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_data); +void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt); +void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_data); + +/* user functions */ +void __acquires(wait_entry) +iwl_init_notification_wait(struct iwl_notif_wait_data *notif_data, + struct iwl_notification_wait *wait_entry, + u8 cmd, + void (*fn)(struct iwl_notif_wait_data *notif_data, + struct iwl_rx_packet *pkt, void *data), + void *fn_data); -#ifndef __iwl_wifi_h__ -#define __iwl_wifi_h__ +int __must_check __releases(wait_entry) +iwl_wait_notification(struct iwl_notif_wait_data *notif_data, + struct iwl_notification_wait *wait_entry, + unsigned long timeout); -#include "iwl-shared.h" +void __releases(wait_entry) +iwl_remove_notification(struct iwl_notif_wait_data *notif_data, + struct iwl_notification_wait *wait_entry); -int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type); -void iwl_send_prio_tbl(struct iwl_trans *trans); -int iwl_init_alive_start(struct iwl_trans *trans); -int iwl_run_init_ucode(struct iwl_trans *trans); -int iwl_load_ucode_wait_alive(struct iwl_trans *trans, - enum iwl_ucode_type ucode_type); -#endif /* __iwl_wifi_h__ */ +#endif /* __iwl_notif_wait_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h new file mode 100644 index 00000000000..6ea4163ff56 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -0,0 +1,216 @@ +/****************************************************************************** + * + * 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 - 2012 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 - 2012 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_op_mode_h__ +#define __iwl_op_mode_h__ + +struct iwl_op_mode; +struct iwl_trans; +struct sk_buff; +struct iwl_device_cmd; +struct iwl_rx_cmd_buffer; +struct iwl_fw; + +/** + * DOC: Operational mode - what is it ? + * + * The operational mode (a.k.a. op_mode) is the layer that implements + * mac80211's handlers. It knows two APIs: mac80211's and the fw's. It uses + * the transport API to access the HW. The op_mode doesn't need to know how the + * underlying HW works, since the transport layer takes care of that. + * + * There can be several op_mode: i.e. different fw APIs will require two + * different op_modes. This is why the op_mode is virtualized. + */ + +/** + * DOC: Life cycle of the Operational mode + * + * The operational mode has a very simple life cycle. + * + * 1) The driver layer (iwl-drv.c) chooses the op_mode based on the + * capabilities advertized by the fw file (in TLV format). + * 2) The driver layer starts the op_mode (ops->start) + * 3) The op_mode registers registers mac80211 + * 4) The op_mode is governed by mac80211 + * 5) The driver layer stops the op_mode + */ + +/** + * struct iwl_op_mode_ops - op_mode specific operations + * + * The op_mode exports its ops so that external components can start it and + * interact with it. The driver layer typically calls the start and stop + * handlers, the transport layer calls the others. + * + * All the handlers MUST be implemented + * + * @start: start the op_mode. The transport layer is already allocated. + * May sleep + * @stop: stop the op_mode. Must free all the memory allocated. + * May sleep + * @rx: Rx notification to the op_mode. rxb is the Rx buffer itself. Cmd is the + * HCMD the this Rx responds to. + * Must be atomic. + * @queue_full: notifies that a HW queue is full. Ac is the ac of the queue + * Must be atomic + * @queue_not_full: notifies that a HW queue is not full any more. + * Ac is the ac of the queue. Must be atomic + * @hw_rf_kill:notifies of a change in the HW rf kill switch. True means that + * the radio is killed. Must be atomic. + * @free_skb: allows the transport layer to free skbs that haven't been + * reclaimed by the op_mode. This can happen when the driver is freed and + * there are Tx packets pending in the transport layer. + * Must be atomic + * @nic_error: error notification. Must be atomic + * @cmd_queue_full: Called when the command queue gets full. Must be atomic. + * @nic_config: configure NIC, called before firmware is started. + * May sleep + */ +struct iwl_op_mode_ops { + struct iwl_op_mode *(*start)(struct iwl_trans *trans, + const struct iwl_fw *fw); + void (*stop)(struct iwl_op_mode *op_mode); + int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); + void (*queue_full)(struct iwl_op_mode *op_mode, u8 ac); + void (*queue_not_full)(struct iwl_op_mode *op_mode, u8 ac); + void (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state); + void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb); + void (*nic_error)(struct iwl_op_mode *op_mode); + void (*cmd_queue_full)(struct iwl_op_mode *op_mode); + void (*nic_config)(struct iwl_op_mode *op_mode); +}; + +/** + * struct iwl_op_mode - operational mode + * + * This holds an implementation of the mac80211 / fw API. + * + * @ops - pointer to its own ops + */ +struct iwl_op_mode { + const struct iwl_op_mode_ops *ops; + const struct iwl_trans *trans; + + char op_mode_specific[0] __aligned(sizeof(void *)); +}; + +static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode) +{ + might_sleep(); + + op_mode->ops->stop(op_mode); +} + +static inline int iwl_op_mode_rx(struct iwl_op_mode *op_mode, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd) +{ + return op_mode->ops->rx(op_mode, rxb, cmd); +} + +static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode, u8 ac) +{ + op_mode->ops->queue_full(op_mode, ac); +} + +static inline void iwl_op_mode_queue_not_full(struct iwl_op_mode *op_mode, + u8 ac) +{ + op_mode->ops->queue_not_full(op_mode, ac); +} + +static inline void iwl_op_mode_hw_rf_kill(struct iwl_op_mode *op_mode, + bool state) +{ + op_mode->ops->hw_rf_kill(op_mode, state); +} + +static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode, + struct sk_buff *skb) +{ + op_mode->ops->free_skb(op_mode, skb); +} + +static inline void iwl_op_mode_nic_error(struct iwl_op_mode *op_mode) +{ + op_mode->ops->nic_error(op_mode); +} + +static inline void iwl_op_mode_cmd_queue_full(struct iwl_op_mode *op_mode) +{ + op_mode->ops->cmd_queue_full(op_mode); +} + +static inline void iwl_op_mode_nic_config(struct iwl_op_mode *op_mode) +{ + might_sleep(); + op_mode->ops->nic_config(op_mode); +} + +/***************************************************** +* Op mode layers implementations +******************************************************/ +extern const struct iwl_op_mode_ops iwl_dvm_ops; + +#endif /* __iwl_op_mode_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index fb30ea7ca96..c5e339ee918 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,118 +64,13 @@ #include <linux/pci.h> #include <linux/pci-aspm.h> -#include "iwl-bus.h" #include "iwl-io.h" #include "iwl-shared.h" #include "iwl-trans.h" #include "iwl-csr.h" #include "iwl-cfg.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_pcie_cap(pci_dev); - 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, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(bus, CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n"); - } -} - -static void iwl_pci_get_hw_id_string(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 u32 iwl_pci_get_hw_id(struct iwl_bus *bus) -{ - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - return (pci_dev->device << 16) + 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 const struct iwl_bus_ops bus_ops_pci = { - .get_pm_support = iwl_pci_is_pm_supported, - .apm_config = iwl_pci_apm_config, - .get_hw_id_string = iwl_pci_get_hw_id_string, - .get_hw_id = iwl_pci_get_hw_id, - .write8 = iwl_pci_write8, - .write32 = iwl_pci_write32, - .read32 = iwl_pci_read32, -}; +#include "iwl-drv.h" +#include "iwl-trans.h" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ @@ -263,9 +158,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6005_2abg_cfg)}, {IWL_PCI_DEVICE(0x0082, 0xC020, iwl6005_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x0085, 0xC220, iwl6005_2agn_sff_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1341, iwl6005_2agn_d_cfg)}, - {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_cfg)},/* low 5GHz active */ - {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_cfg)},/* high 5GHz active */ + {IWL_PCI_DEVICE(0x0082, 0x4820, iwl6005_2agn_d_cfg)}, + {IWL_PCI_DEVICE(0x0082, 0x1304, iwl6005_2agn_mow1_cfg)},/* low 5GHz active */ + {IWL_PCI_DEVICE(0x0082, 0x1305, iwl6005_2agn_mow2_cfg)},/* high 5GHz active */ /* 6x30 Series */ {IWL_PCI_DEVICE(0x008A, 0x5305, iwl1030_bgn_cfg)}, @@ -346,6 +241,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {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, 0x4860, iwl6035_2agn_cfg)}, /* 105 Series */ {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, @@ -362,132 +258,62 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + 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_bus *bus; - struct iwl_pci_bus *pci_bus; - u16 pci_cmd; + const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + struct iwl_shared *shrd; + struct iwl_trans *iwl_trans; int err; - bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); - if (!bus) { + shrd = kzalloc(sizeof(*iwl_trans->shrd), GFP_KERNEL); + if (!shrd) { dev_printk(KERN_ERR, &pdev->dev, - "Couldn't allocate iwl_pci_bus"); + "Couldn't allocate iwl_shared"); err = -ENOMEM; - goto out_no_pci; + goto out_free_bus; } - pci_bus = IWL_BUS_GET_PCI_BUS(bus); - pci_bus->pci_dev = pdev; - - pci_set_drvdata(pdev, bus); - - /* 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) { - dev_printk(KERN_ERR, bus->dev, - "No suitable DMA available.\n"); - goto out_pci_disable_device; - } - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed"); - goto out_pci_disable_device; - } - - pci_bus->hw_base = pci_iomap(pdev, 0, 0); - if (!pci_bus->hw_base) { - dev_printk(KERN_ERR, bus->dev, "pci_iomap failed"); - err = -ENODEV; - goto out_pci_release_regions; +#ifdef CONFIG_IWLWIFI_IDI + iwl_trans = iwl_trans_idi_alloc(shrd, pdev, ent); +#else + iwl_trans = iwl_trans_pcie_alloc(shrd, pdev, ent); +#endif + if (iwl_trans == NULL) { + err = -ENOMEM; + goto out_free_bus; } - dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_base = %p\n", pci_bus->hw_base); + shrd->trans = iwl_trans; + pci_set_drvdata(pdev, iwl_trans); - dev_printk(KERN_INFO, &pdev->dev, - "HW Revision ID = 0x%X\n", pdev->revision); - - /* 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); + err = iwl_drv_start(shrd, iwl_trans, cfg); if (err) - dev_printk(KERN_ERR, &pdev->dev, - "pci_enable_msi failed(0X%x)", err); - - /* 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); - } - - bus->dev = &pdev->dev; - bus->irq = pdev->irq; - bus->ops = &bus_ops_pci; + goto out_free_trans; - err = iwl_probe(bus, &trans_ops_pcie, cfg); - if (err) - goto out_disable_msi; return 0; -out_disable_msi: - pci_disable_msi(pdev); - pci_iounmap(pdev, pci_bus->hw_base); -out_pci_release_regions: +out_free_trans: + iwl_trans_free(iwl_trans); pci_set_drvdata(pdev, NULL); - pci_release_regions(pdev); -out_pci_disable_device: - pci_disable_device(pdev); -out_no_pci: - kfree(bus); +out_free_bus: + kfree(shrd); return err; } static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - struct iwl_bus *bus = pci_get_drvdata(pdev); - struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - struct iwl_shared *shrd = bus->shrd; + struct iwl_trans *iwl_trans = pci_get_drvdata(pdev); + struct iwl_shared *shrd = iwl_trans->shrd; - iwl_remove(shrd->priv); + iwl_drv_stop(shrd); + iwl_trans_free(shrd->trans); - pci_disable_msi(pci_dev); - pci_iounmap(pci_dev, pci_bus->hw_base); - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - pci_set_drvdata(pci_dev, NULL); + pci_set_drvdata(pdev, NULL); - kfree(bus); + kfree(shrd); } #ifdef CONFIG_PM_SLEEP @@ -495,22 +321,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) static int iwl_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_bus *bus = pci_get_drvdata(pdev); - struct iwl_shared *shrd = bus->shrd; + struct iwl_trans *iwl_trans = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx. */ - return iwl_trans_suspend(shrd->trans); + return iwl_trans_suspend(iwl_trans); } static int iwl_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_bus *bus = pci_get_drvdata(pdev); - struct iwl_shared *shrd = bus->shrd; + struct iwl_trans *iwl_trans = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if @@ -523,7 +347,7 @@ static int iwl_pci_resume(struct device *device) */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - return iwl_trans_resume(shrd->trans); + return iwl_trans_resume(iwl_trans); } static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 2b188a6025b..958d9d09aee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -215,7 +215,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, else cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK; - if (hw_params(priv).shadow_reg_enable) + if (cfg(priv)->base_params->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; @@ -301,7 +301,7 @@ static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv, if (priv->power_data.bus_pm) cmd->flags |= IWL_POWER_PCI_PM_MSK; - if (hw_params(priv).shadow_reg_enable) + if (cfg(priv)->base_params->shadow_reg_enable) cmd->flags |= IWL_POWER_SHADOW_REG_ENA; else cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; @@ -336,7 +336,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) le32_to_cpu(cmd->sleep_interval[3]), le32_to_cpu(cmd->sleep_interval[4])); - return iwl_trans_send_cmd_pdu(trans(priv), POWER_TABLE_CMD, CMD_SYNC, + return iwl_dvm_send_cmd_pdu(priv, POWER_TABLE_CMD, CMD_SYNC, sizeof(struct iwl_powertable_cmd), cmd); } @@ -348,7 +348,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (priv->shrd->wowlan) + if (priv->wowlan) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); else if (!cfg(priv)->base_params->no_idle_support && priv->hw->conf.flags & IEEE80211_CONF_IDLE) @@ -383,7 +383,7 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, int ret; bool update_chains; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* Don't update the RX chain when chain noise calibration is running */ update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || @@ -392,12 +392,12 @@ int iwl_power_set_mode(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd, if (!memcmp(&priv->power_data.sleep_cmd, cmd, sizeof(*cmd)) && !force) return 0; - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return -EIO; /* scan complete use sleep_power_next, need to be updated */ memcpy(&priv->power_data.sleep_cmd_next, cmd, sizeof(*cmd)); - if (test_bit(STATUS_SCANNING, &priv->shrd->status) && !force) { + if (test_bit(STATUS_SCANNING, &priv->status) && !force) { IWL_DEBUG_INFO(priv, "Defer power set mode while scanning\n"); return 0; } @@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { - priv->power_data.bus_pm = bus_get_pm_support(bus(priv)); + priv->power_data.bus_pm = trans(priv)->pm_support; priv->power_data.debug_sleep_level_override = -1; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 5f7b720cf1a..07a19fce5fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index bebdd828f32..75dc20bd965 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -216,10 +216,6 @@ #define SCD_TRANS_TBL_OFFSET_QUEUE(x) \ ((SCD_TRANS_TBL_MEM_LOWER_BOUND + ((x) * 2)) & 0xfffc) -#define SCD_QUEUECHAIN_SEL_ALL(priv) \ - (((1<<hw_params(priv).max_txq_num) - 1) &\ - (~(1<<(priv)->shrd->cmd_queue))) - #define SCD_BASE (PRPH_BASE + 0xa02c00) #define SCD_SRAM_BASE_ADDR (SCD_BASE + 0x0) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a6454726737..902efe4bc89 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -57,39 +57,39 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) { int ret; - struct iwl_rx_packet *pkt; struct iwl_host_cmd cmd = { .id = REPLY_SCAN_ABORT_CMD, .flags = CMD_SYNC | CMD_WANT_SKB, }; + __le32 *status; /* Exit instantly with error when device is not ready * to receive scan abort command or it does not perform * hardware scan currently */ - if (!test_bit(STATUS_READY, &priv->shrd->status) || - !test_bit(STATUS_GEO_CONFIGURED, &priv->shrd->status) || - !test_bit(STATUS_SCAN_HW, &priv->shrd->status) || - test_bit(STATUS_FW_ERROR, &priv->shrd->status) || - test_bit(STATUS_EXIT_PENDING, &priv->shrd->status)) + if (!test_bit(STATUS_READY, &priv->status) || + !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || + !test_bit(STATUS_SCAN_HW, &priv->status) || + test_bit(STATUS_FW_ERROR, &priv->shrd->status)) return -EIO; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) return ret; - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->u.status != CAN_ABORT_STATUS) { + status = (void *)cmd.resp_pkt->data; + if (*status != CAN_ABORT_STATUS) { /* The scan abort will return 1 for success or * 2 for "failure". A failure condition can be * due to simply not being in an active scan which * can occur if we send the scan abort before we * the microcode has notified us that a scan is * completed. */ - IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); + IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", + le32_to_cpu(*status)); ret = -EIO; } - iwl_free_pages(priv->shrd, cmd.reply_page); + iwl_free_resp(&cmd); return ret; } @@ -116,20 +116,20 @@ static void iwl_process_scan_complete(struct iwl_priv *priv) { bool aborted; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); - if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status)) + if (!test_and_clear_bit(STATUS_SCAN_COMPLETE, &priv->status)) return; IWL_DEBUG_SCAN(priv, "Completed scan.\n"); cancel_delayed_work(&priv->scan_check); - aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); + aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); if (aborted) IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); - if (!test_and_clear_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); goto out_settings; } @@ -165,7 +165,7 @@ out_complete: out_settings: /* Can we still talk to firmware ? */ - if (!iwl_is_ready_rf(priv->shrd)) + if (!iwl_is_ready_rf(priv)) return; iwlagn_post_scan(priv); @@ -173,18 +173,18 @@ out_settings: void iwl_force_scan_end(struct iwl_priv *priv) { - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); - if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (!test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); return; } IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); - clear_bit(STATUS_SCANNING, &priv->shrd->status); - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); - clear_bit(STATUS_SCAN_ABORTING, &priv->shrd->status); - clear_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); + clear_bit(STATUS_SCANNING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + clear_bit(STATUS_SCAN_COMPLETE, &priv->status); iwl_complete_scan(priv, true); } @@ -192,14 +192,14 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); - if (!test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (!test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); return; } - if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { + if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); return; } @@ -218,7 +218,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv) int iwl_scan_cancel(struct iwl_priv *priv) { IWL_DEBUG_SCAN(priv, "Queuing abort scan\n"); - queue_work(priv->shrd->workqueue, &priv->abort_scan); + queue_work(priv->workqueue, &priv->abort_scan); return 0; } @@ -231,14 +231,14 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) { unsigned long timeout = jiffies + msecs_to_jiffies(ms); - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); iwl_do_scan_abort(priv); while (time_before_eq(jiffies, timeout)) { - if (!test_bit(STATUS_SCAN_HW, &priv->shrd->status)) + if (!test_bit(STATUS_SCAN_HW, &priv->status)) goto finished; msleep(20); } @@ -261,13 +261,12 @@ void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) /* Service response to REPLY_SCAN_CMD (0x80) */ static int iwl_rx_reply_scan(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scanreq_notification *notif = - (struct iwl_scanreq_notification *)pkt->u.raw; + struct iwl_scanreq_notification *notif = (void *)pkt->data; IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); #endif @@ -276,12 +275,12 @@ static int iwl_rx_reply_scan(struct iwl_priv *priv, /* Service SCAN_START_NOTIFICATION (0x82) */ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scanstart_notification *notif = - (struct iwl_scanstart_notification *)pkt->u.raw; + struct iwl_scanstart_notification *notif = (void *)pkt->data; + priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); IWL_DEBUG_SCAN(priv, "Scan start: " "%d [802.11%s] " @@ -303,13 +302,12 @@ static int iwl_rx_scan_start_notif(struct iwl_priv *priv, /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scanresults_notification *notif = - (struct iwl_scanresults_notification *)pkt->u.raw; + struct iwl_scanresults_notification *notif = (void *)pkt->data; IWL_DEBUG_SCAN(priv, "Scan ch.res: " "%d [802.11%s] " @@ -329,11 +327,11 @@ static int iwl_rx_scan_results_notif(struct iwl_priv *priv, /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; + struct iwl_scancomplete_notification *scan_notif = (void *)pkt->data; IWL_DEBUG_SCAN(priv, "Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", scan_notif->scanned_channels, @@ -352,9 +350,9 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, * to clear, we need to set SCAN_COMPLETE before clearing SCAN_HW * to avoid a race there. */ - set_bit(STATUS_SCAN_COMPLETE, &priv->shrd->status); - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); - queue_work(priv->shrd->workqueue, &priv->scan_completed); + set_bit(STATUS_SCAN_COMPLETE, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + queue_work(priv->workqueue, &priv->scan_completed); if (priv->iw_mode != NL80211_IFTYPE_ADHOC && iwl_advanced_bt_coexist(priv) && @@ -374,7 +372,7 @@ static int iwl_rx_scan_complete_notif(struct iwl_priv *priv, IWL_BT_COEX_TRAFFIC_LOAD_NONE; } priv->bt_status = scan_notif->bt_status; - queue_work(priv->shrd->workqueue, + queue_work(priv->workqueue, &priv->bt_traffic_change_work); } return 0; @@ -414,10 +412,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) for_each_context(priv, ctx) { u16 value; - if (!iwl_is_associated_ctx(ctx)) - continue; - if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P) + switch (ctx->staging.dev_type) { + case RXON_DEV_TYPE_P2P: + /* no timing constraints */ continue; + case RXON_DEV_TYPE_ESS: + default: + /* timing constraints if associated */ + if (!iwl_is_associated_ctx(ctx)) + continue; + break; + case RXON_DEV_TYPE_CP: + case RXON_DEV_TYPE_2STA: + /* + * These seem to always have timers for TBTT + * active in uCode even when not associated yet. + */ + break; + } + value = ctx->beacon_int; if (!value) value = IWL_PASSIVE_DWELL_BASE; @@ -559,6 +572,53 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, return added; } +/** + * iwl_fill_probe_req - fill in all required fields and IE for probe request + */ + +static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, + const u8 *ies, int ie_len, int left) +{ + int len = 0; + u8 *pos = NULL; + + /* Make sure there is enough space for the probe request, + * two mandatory IEs and the data */ + left -= 24; + if (left < 0) + return 0; + + frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); + memcpy(frame->sa, ta, ETH_ALEN); + memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); + frame->seq_ctrl = 0; + + len += 24; + + /* ...next IE... */ + pos = &frame->u.probe_req.variable[0]; + + /* fill in our indirect SSID IE */ + left -= 2; + if (left < 0) + return 0; + *pos++ = WLAN_EID_SSID; + *pos++ = 0; + + len += 2; + + if (WARN_ON(left < ie_len)) + return len; + + if (ies && ie_len) { + memcpy(pos, ies, ie_len); + len += ie_len; + } + + return (u16)len; +} + static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { @@ -581,7 +641,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) u8 scan_tx_antennas = hw_params(priv).valid_tx_ant; int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); if (vif) ctx = iwl_rxon_ctx_from_vif(vif); @@ -778,7 +838,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->rx_chain = cpu_to_le16(rx_chain); switch (priv->scan_type) { case IWL_SCAN_NORMAL: - cmd_len = iwl_fill_probe_req(priv, + cmd_len = iwl_fill_probe_req( (struct ieee80211_mgmt *)scan->data, vif->addr, priv->scan_request->ie, @@ -788,7 +848,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) case IWL_SCAN_RADIO_RESET: case IWL_SCAN_ROC: /* use bcast addr, will not be transmitted but must be valid */ - cmd_len = iwl_fill_probe_req(priv, + cmd_len = iwl_fill_probe_req( (struct ieee80211_mgmt *)scan->data, iwl_bcast_addr, NULL, 0, IWL_MAX_SCAN_SIZE - sizeof(*scan)); @@ -867,15 +927,15 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->len = cpu_to_le16(cmd.len[0]); /* set scan bit here for PAN params */ - set_bit(STATUS_SCAN_HW, &priv->shrd->status); + set_bit(STATUS_SCAN_HW, &priv->status); ret = iwlagn_set_pan_params(priv); if (ret) return ret; - ret = iwl_trans_send_cmd(trans(priv), &cmd); + ret = iwl_dvm_send_cmd(priv, &cmd); if (ret) { - clear_bit(STATUS_SCAN_HW, &priv->shrd->status); + clear_bit(STATUS_SCAN_HW, &priv->status); iwlagn_set_pan_params(priv); } @@ -898,22 +958,22 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, { int ret; - lockdep_assert_held(&priv->shrd->mutex); + lockdep_assert_held(&priv->mutex); cancel_delayed_work(&priv->scan_check); - if (!iwl_is_ready_rf(priv->shrd)) { + if (!iwl_is_ready_rf(priv)) { IWL_WARN(priv, "Request scan called when driver not ready.\n"); return -EIO; } - if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_HW, &priv->status)) { IWL_DEBUG_SCAN(priv, "Multiple concurrent scan requests in parallel.\n"); return -EBUSY; } - if (test_bit(STATUS_SCAN_ABORTING, &priv->shrd->status)) { + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); return -EBUSY; } @@ -923,19 +983,19 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, scan_type == IWL_SCAN_ROC ? "remain-on-channel " : "internal short "); - set_bit(STATUS_SCANNING, &priv->shrd->status); + set_bit(STATUS_SCANNING, &priv->status); priv->scan_type = scan_type; priv->scan_start = jiffies; priv->scan_band = band; ret = iwlagn_request_scan(priv, vif); if (ret) { - clear_bit(STATUS_SCANNING, &priv->shrd->status); + clear_bit(STATUS_SCANNING, &priv->status); priv->scan_type = IWL_SCAN_NORMAL; return ret; } - queue_delayed_work(priv->shrd->workqueue, &priv->scan_check, + queue_delayed_work(priv->workqueue, &priv->scan_check, IWL_SCAN_CHECK_WATCHDOG); return 0; @@ -948,7 +1008,7 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv, */ void iwl_internal_short_hw_scan(struct iwl_priv *priv) { - queue_work(priv->shrd->workqueue, &priv->start_internal_scan); + queue_work(priv->workqueue, &priv->start_internal_scan); } static void iwl_bg_start_internal_scan(struct work_struct *work) @@ -958,14 +1018,14 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) IWL_DEBUG_SCAN(priv, "Start internal scan\n"); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); if (priv->scan_type == IWL_SCAN_RADIO_RESET) { IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n"); goto unlock; } - if (test_bit(STATUS_SCANNING, &priv->shrd->status)) { + if (test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); goto unlock; } @@ -973,7 +1033,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work) if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band)) IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); unlock: - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } static void iwl_bg_scan_check(struct work_struct *data) @@ -986,56 +1046,9 @@ static void iwl_bg_scan_check(struct work_struct *data) /* Since we are here firmware does not finish scan and * most likely is in bad shape, so we don't bother to * send abort command, just force scan complete to mac80211 */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_force_scan_end(priv); - mutex_unlock(&priv->shrd->mutex); -} - -/** - * iwl_fill_probe_req - fill in all required fields and IE for probe request - */ - -u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, - const u8 *ta, const u8 *ies, int ie_len, int left) -{ - int len = 0; - u8 *pos = NULL; - - /* Make sure there is enough space for the probe request, - * two mandatory IEs and the data */ - left -= 24; - if (left < 0) - return 0; - - frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); - memcpy(frame->sa, ta, ETH_ALEN); - memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); - frame->seq_ctrl = 0; - - len += 24; - - /* ...next IE... */ - pos = &frame->u.probe_req.variable[0]; - - /* fill in our indirect SSID IE */ - left -= 2; - if (left < 0) - return 0; - *pos++ = WLAN_EID_SSID; - *pos++ = 0; - - len += 2; - - if (WARN_ON(left < ie_len)) - return len; - - if (ies && ie_len) { - memcpy(pos, ies, ie_len); - len += ie_len; - } - - return (u16)len; + mutex_unlock(&priv->mutex); } static void iwl_bg_abort_scan(struct work_struct *work) @@ -1046,9 +1059,9 @@ static void iwl_bg_abort_scan(struct work_struct *work) /* We keep scan_check work queued in case when firmware will not * report back scan completed notification */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_scan_cancel_timeout(priv, 200); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } static void iwl_bg_scan_completed(struct work_struct *work) @@ -1056,9 +1069,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_process_scan_complete(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } void iwl_setup_scan_deferred_work(struct iwl_priv *priv) @@ -1076,8 +1089,8 @@ void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->scan_completed); if (cancel_delayed_work_sync(&priv->scan_check)) { - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); iwl_force_scan_end(priv); - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index dc55cc4a810..b515d657a0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,12 +65,11 @@ #include <linux/types.h> #include <linux/spinlock.h> -#include <linux/mutex.h> #include <linux/gfp.h> -#include <linux/mm.h> /* for page_address */ #include <net/mac80211.h> #include "iwl-commands.h" +#include "iwl-fw.h" /** * DOC: shared area - role and goal @@ -94,7 +93,6 @@ * This implementation is iwl-pci.c */ -struct iwl_bus; struct iwl_priv; struct iwl_trans; struct iwl_sensitivity_ranges; @@ -102,7 +100,7 @@ struct iwl_trans_ops; #define DRV_NAME "iwlwifi" #define IWLWIFI_VERSION "in-tree:" -#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2012 Intel Corporation" #define DRV_AUTHOR "<ilw@linux.intel.com>" extern struct iwl_mod_params iwlagn_mod_params; @@ -117,7 +115,6 @@ extern struct iwl_mod_params iwlagn_mod_params; * Holds the module parameters * * @sw_crypto: using hardware encryption, default = 0 - * @num_of_queues: number of tx queue, HW dependent * @disable_11n: disable 11n capabilities, default = 0, * use IWL_DISABLE_HT_* constants * @amsdu_size_8K: enable 8K amsdu size, default = 1 @@ -139,7 +136,6 @@ extern struct iwl_mod_params iwlagn_mod_params; */ struct iwl_mod_params { int sw_crypto; - int num_of_queues; unsigned int disable_11n; int amsdu_size_8K; int antenna; @@ -164,7 +160,6 @@ struct iwl_mod_params { * * Holds the module parameters * - * @max_txq_num: Max # Tx queues supported * @num_ampdu_queues: num of ampdu queues * @tx_chains_num: Number of TX chains * @rx_chains_num: Number of RX chains @@ -173,27 +168,23 @@ struct iwl_mod_params { * @ht40_channel: is 40MHz width possible: BIT(IEEE80211_BAND_XXX) * @sku: sku read from EEPROM * @rx_page_order: Rx buffer page order - * @max_inst_size: for ucode use - * @max_data_size: for ucode use * @ct_kill_threshold: temperature threshold - in hw dependent unit * @ct_kill_exit_threshold: when to reeable the device - in hw dependent unit * relevant for 1000, 6000 and up * @wd_timeout: TX queues watchdog timeout * @struct iwl_sensitivity_ranges: range of sensitivity values + * @use_rts_for_aggregation: use rts/cts protection for HT traffic */ struct iwl_hw_params { - u8 max_txq_num; u8 num_ampdu_queues; u8 tx_chains_num; u8 rx_chains_num; u8 valid_tx_ant; u8 valid_rx_ant; u8 ht40_channel; - bool shadow_reg_enable; + bool use_rts_for_aggregation; u16 sku; u32 rx_page_order; - u32 max_inst_size; - u32 max_data_size; u32 ct_kill_threshold; u32 ct_kill_exit_threshold; unsigned int wd_timeout; @@ -201,62 +192,6 @@ struct iwl_hw_params { const struct iwl_sensitivity_ranges *sens; }; -/** - * enum iwl_ucode_type - * - * The type of ucode currently loaded on the hardware. - * - * @IWL_UCODE_NONE: No ucode loaded - * @IWL_UCODE_REGULAR: Normal runtime ucode - * @IWL_UCODE_INIT: Initial ucode - * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode - */ -enum iwl_ucode_type { - IWL_UCODE_NONE, - IWL_UCODE_REGULAR, - IWL_UCODE_INIT, - IWL_UCODE_WOWLAN, -}; - -/** - * struct iwl_notification_wait - notification wait entry - * @list: list head for global list - * @fn: function called with the notification - * @cmd: command ID - * - * This structure is not used directly, to wait for a - * notification declare it on the stack, and call - * iwlagn_init_notification_wait() with appropriate - * parameters. Then do whatever will cause the ucode - * to notify the driver, and to wait for that then - * call iwlagn_wait_notification(). - * - * Each notification is one-shot. If at some point we - * need to support multi-shot notifications (which - * can't be allocated on the stack) we need to modify - * the code for them. - */ -struct iwl_notification_wait { - struct list_head list; - - void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt, - void *data); - void *fn_data; - - u8 cmd; - bool triggered, aborted; -}; - -/** - * enum iwl_pa_type - Power Amplifier type - * @IWL_PA_SYSTEM: based on uCode configuration - * @IWL_PA_INTERNAL: use Internal only - */ -enum iwl_pa_type { - IWL_PA_SYSTEM = 0, - IWL_PA_INTERNAL = 1, -}; - /* * LED mode * IWL_LED_DEFAULT: use device default @@ -264,11 +199,80 @@ enum iwl_pa_type { * LED ON = RF ON * LED OFF = RF OFF * IWL_LED_BLINK: adjust led blink rate based on blink table + * IWL_LED_DISABLE: led disabled */ enum iwl_led_mode { IWL_LED_DEFAULT, IWL_LED_RF_STATE, IWL_LED_BLINK, + IWL_LED_DISABLE, +}; + +/* + * @max_ll_items: max number of OTP blocks + * @shadow_ram_support: shadow support for OTP memory + * @led_compensation: compensate on the led on/off time per HW according + * 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 + * @adv_thermal_throttle: support advance thermal throttle + * @support_ct_kill_exit: support ct kill exit condition + * @support_wimax_coexist: support wimax/wifi co-exist + * @plcp_delta_threshold: plcp error rate threshold used to trigger + * radio tuning when there is a high receiving plcp error rate + * @chain_noise_scale: default chain noise scale used for gain computation + * @wd_timeout: TX queues watchdog timeout + * @max_event_log_size: size of event log buffer size for ucode event logging + * @shadow_reg_enable: HW shadhow register bit + * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up + * @no_idle_support: do not support idle mode + * wd_disable: disable watchdog timer + */ +struct iwl_base_params { + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues;/* def: HW dependent */ + /* for iwl_apm_init() */ + u32 pll_cfg_val; + + const u16 max_ll_items; + const bool shadow_ram_support; + u16 led_compensation; + bool adv_thermal_throttle; + bool support_ct_kill_exit; + const bool support_wimax_coexist; + u8 plcp_delta_threshold; + s32 chain_noise_scale; + unsigned int wd_timeout; + u32 max_event_log_size; + const bool shadow_reg_enable; + const bool hd_v2; + const bool no_idle_support; + const bool wd_disable; +}; + +/* + * @advanced_bt_coexist: support advanced bt coexist + * @bt_init_traffic_load: specify initial bt traffic load + * @bt_prio_boost: default bt priority boost value + * @agg_time_limit: maximum number of uSec in aggregation + * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode + */ +struct iwl_bt_params { + bool advanced_bt_coexist; + u8 bt_init_traffic_load; + u8 bt_prio_boost; + u16 agg_time_limit; + bool bt_sco_disable; + bool bt_session_2; +}; +/* + * @use_rts_for_aggregation: use rts/cts protection for HT traffic + */ +struct iwl_ht_params { + const bool ht_greenfield_support; /* if used set to true */ + bool use_rts_for_aggregation; + enum ieee80211_smps_mode smps_mode; }; /** @@ -281,9 +285,10 @@ enum iwl_led_mode { * @ucode_api_ok: oldest version of the uCode API that is OK to load * without a warning, for use in transitions * @ucode_api_min: Lowest version of uCode API supported by driver. + * @max_inst_size: The maximal length of the fw inst section + * @max_data_size: The maximal length of the fw data section * @valid_tx_ant: valid transmit antenna * @valid_rx_ant: valid receive antenna - * @sku: sku information from EEPROM * @eeprom_ver: EEPROM version * @eeprom_calib_ver: EEPROM calibration version * @lib: pointer to the lib ops @@ -291,7 +296,6 @@ enum iwl_led_mode { * @base_params: pointer to basic parameters * @ht_params: point to ht patameters * @bt_params: pointer to bt parameters - * @pa_type: used by 6000 series only to identify the type of Power Amplifier * @need_temp_offset_calib: need to perform temperature offset calibration * @no_xtal_calib: some devices do not need crystal calibration data, * don't send it to those @@ -318,19 +322,19 @@ struct iwl_cfg { const unsigned int ucode_api_max; const unsigned int ucode_api_ok; const unsigned int ucode_api_min; + const u32 max_data_size; + const u32 max_inst_size; u8 valid_tx_ant; u8 valid_rx_ant; - u16 sku; u16 eeprom_ver; u16 eeprom_calib_ver; const struct iwl_lib_ops *lib; void (*additional_nic_config)(struct iwl_priv *priv); /* params not likely to change within a device family */ - struct iwl_base_params *base_params; + const struct iwl_base_params *base_params; /* params likely to change within a device family */ - struct iwl_ht_params *ht_params; - struct iwl_bt_params *bt_params; - enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ + const struct iwl_ht_params *ht_params; + const struct iwl_bt_params *bt_params; const bool need_temp_offset_calib; /* if used set to true */ const bool no_xtal_calib; u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; @@ -345,10 +349,6 @@ struct iwl_cfg { /** * struct iwl_shared - shared fields for all the layers of the driver * - * @dbg_level_dev: dbg level set per device. Prevails on - * iwlagn_mod_params.debug_level if set (!= 0) - * @ucode_owner: IWL_OWNERSHIP_* - * @cmd_queue: command queue number * @status: STATUS_* * @wowlan: are we running wowlan uCode * @valid_contexts: microcode/device supports multiple contexts @@ -356,45 +356,22 @@ struct iwl_cfg { * @cfg: see struct iwl_cfg * @priv: pointer to the upper layer data * @trans: pointer to the transport layer data + * @nic: pointer to the nic data * @hw_params: see struct iwl_hw_params - * @workqueue: the workqueue used by all the layers of the driver * @lock: protect general shared data - * @sta_lock: protects the station table. - * If lock and sta_lock are needed, lock must be acquired first. - * @mutex: - * @wait_command_queue: the wait_queue for SYNC host command nad uCode load * @eeprom: pointer to the eeprom/OTP image * @ucode_type: indicator of loaded ucode image - * @notif_waits: things waiting for notification - * @notif_wait_lock: lock protecting notification - * @notif_waitq: head of notification wait queue * @device_pointers: pointers to ucode event tables */ struct iwl_shared { -#ifdef CONFIG_IWLWIFI_DEBUG - u32 dbg_level_dev; -#endif /* CONFIG_IWLWIFI_DEBUG */ - -#define IWL_OWNERSHIP_DRIVER 0 -#define IWL_OWNERSHIP_TM 1 - u8 ucode_owner; - u8 cmd_queue; unsigned long status; - bool wowlan; u8 valid_contexts; - struct iwl_bus *bus; - struct iwl_cfg *cfg; - struct iwl_priv *priv; + const struct iwl_cfg *cfg; struct iwl_trans *trans; + void *drv; struct iwl_hw_params hw_params; - - struct workqueue_struct *workqueue; - spinlock_t lock; - spinlock_t sta_lock; - struct mutex mutex; - - wait_queue_head_t wait_command_queue; + const struct iwl_fw *fw; /* eeprom -- this is in the card's little endian byte order */ u8 *eeprom; @@ -402,11 +379,6 @@ struct iwl_shared { /* ucode related variables */ enum iwl_ucode_type ucode_type; - /* notification wait support */ - struct list_head notif_waits; - spinlock_t notif_wait_lock; - wait_queue_head_t notif_waitq; - struct { u32 error_event_table; u32 log_event_table; @@ -414,112 +386,14 @@ struct iwl_shared { }; -/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ -#define priv(_m) ((_m)->shrd->priv) +/*Whatever _m is (iwl_trans, iwl_priv, these macros will work */ #define cfg(_m) ((_m)->shrd->cfg) -#define bus(_m) ((_m)->shrd->bus) #define trans(_m) ((_m)->shrd->trans) #define hw_params(_m) ((_m)->shrd->hw_params) -#ifdef CONFIG_IWLWIFI_DEBUG -/* - * iwl_get_debug_level: Return active debug level for device - * - * Using sysfs it is possible to set per device debug level. This debug - * level will be used if set, otherwise the global debug level which can be - * set via module parameter is used. - */ -static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) +static inline bool iwl_have_debug_level(u32 level) { - if (shrd->dbg_level_dev) - return shrd->dbg_level_dev; - else - return iwlagn_mod_params.debug_level; -} -#else -static inline u32 iwl_get_debug_level(struct iwl_shared *shrd) -{ - return iwlagn_mod_params.debug_level; -} -#endif - -static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page) -{ - free_pages(page, shrd->hw_params.rx_page_order); -} - -/** - * iwl_queue_inc_wrap - increment queue index, wrap back to beginning - * @index -- current index - * @n_bd -- total number of entries in queue (must be power of 2) - */ -static inline int iwl_queue_inc_wrap(int index, int n_bd) -{ - return ++index & (n_bd - 1); -} - -/** - * iwl_queue_dec_wrap - decrement queue index, wrap back to end - * @index -- current index - * @n_bd -- total number of entries in queue (must be power of 2) - */ -static inline int iwl_queue_dec_wrap(int index, int n_bd) -{ - return --index & (n_bd - 1); -} - -struct iwl_rx_mem_buffer { - dma_addr_t page_dma; - struct page *page; - struct list_head list; -}; - -#define rxb_addr(r) page_address(r->page) - -/* - * mac80211 queues, ACs, hardware queues, FIFOs. - * - * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues - * - * Mac80211 uses the following numbers, which we get as from it - * by way of skb_get_queue_mapping(skb): - * - * VO 0 - * VI 1 - * BE 2 - * BK 3 - * - * - * Regular (not A-MPDU) frames are put into hardware queues corresponding - * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their - * own queue per aggregation session (RA/TID combination), such queues are - * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In - * order to map frames to the right queue, we also need an AC->hw queue - * mapping. This is implemented here. - * - * Due to the way hw queues are set up (by the hw specific modules like - * iwl-4965.c, iwl-5000.c etc.), the AC->hw queue mapping is the identity - * mapping. - */ - -static const u8 tid_to_ac[] = { - IEEE80211_AC_BE, - IEEE80211_AC_BK, - IEEE80211_AC_BK, - IEEE80211_AC_BE, - IEEE80211_AC_VI, - IEEE80211_AC_VI, - IEEE80211_AC_VO, - IEEE80211_AC_VO -}; - -static inline int get_ac_from_tid(u16 tid) -{ - if (likely(tid < ARRAY_SIZE(tid_to_ac))) - return tid_to_ac[tid]; - - /* no support for TIDs 8-15 yet */ - return -EINVAL; + return iwlagn_mod_params.debug_level & level; } enum iwl_rxon_context_id { @@ -529,64 +403,10 @@ enum iwl_rxon_context_id { NUM_IWL_RXON_CTX }; -int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, - struct iwl_cfg *cfg); -void __devexit iwl_remove(struct iwl_priv * priv); -struct iwl_device_cmd; -int __must_check iwl_rx_dispatch(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, - struct iwl_device_cmd *cmd); - int iwlagn_hw_valid_rtc_data_addr(u32 addr); -void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); -void iwl_nic_config(struct iwl_priv *priv); -void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); -void iwl_apm_stop(struct iwl_priv *priv); -int iwl_apm_init(struct iwl_priv *priv); -void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); const char *get_cmd_string(u8 cmd); -bool iwl_check_for_ct_kill(struct iwl_priv *priv); - -void iwl_stop_sw_queue(struct iwl_priv *priv, u8 ac); -void iwl_wake_sw_queue(struct iwl_priv *priv, u8 ac); - -/* notification wait support */ -void iwl_abort_notification_waits(struct iwl_shared *shrd); -void __acquires(wait_entry) -iwl_init_notification_wait(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - u8 cmd, - void (*fn)(struct iwl_trans *trans, - struct iwl_rx_packet *pkt, - void *data), - void *fn_data); -int __must_check __releases(wait_entry) -iwl_wait_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - unsigned long timeout); -void __releases(wait_entry) -iwl_remove_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry); - -#ifdef CONFIG_IWLWIFI_DEBUGFS -void iwl_reset_traffic_log(struct iwl_priv *priv); -#endif /* CONFIG_IWLWIFI_DEBUGFS */ - -#ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv, - enum iwl_rxon_context_id ctxid); -#else -static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, - enum iwl_rxon_context_id ctxid) -{ -} -#endif #define IWL_CMD(x) case x: return #x -#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) - -#define IWL_TRAFFIC_ENTRIES (256) -#define IWL_TRAFFIC_ENTRY_SIZE (64) /***************************************************** * DRIVER STATUS FUNCTIONS @@ -612,46 +432,4 @@ static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, #define STATUS_CHANNEL_SWITCH_PENDING 19 #define STATUS_SCAN_COMPLETE 20 -static inline int iwl_is_ready(struct iwl_shared *shrd) -{ - /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are - * set but EXIT_PENDING is not */ - return test_bit(STATUS_READY, &shrd->status) && - test_bit(STATUS_GEO_CONFIGURED, &shrd->status) && - !test_bit(STATUS_EXIT_PENDING, &shrd->status); -} - -static inline int iwl_is_alive(struct iwl_shared *shrd) -{ - return test_bit(STATUS_ALIVE, &shrd->status); -} - -static inline int iwl_is_init(struct iwl_shared *shrd) -{ - return test_bit(STATUS_INIT, &shrd->status); -} - -static inline int iwl_is_rfkill_hw(struct iwl_shared *shrd) -{ - return test_bit(STATUS_RF_KILL_HW, &shrd->status); -} - -static inline int iwl_is_rfkill(struct iwl_shared *shrd) -{ - return iwl_is_rfkill_hw(shrd); -} - -static inline int iwl_is_ctkill(struct iwl_shared *shrd) -{ - return test_bit(STATUS_CT_KILL, &shrd->status); -} - -static inline int iwl_is_ready_rf(struct iwl_shared *shrd) -{ - if (iwl_is_rfkill(shrd)) - return 0; - - return iwl_is_ready(shrd); -} - #endif /* #__iwl_shared_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 4a5cddd2d56..76f7f925143 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -70,7 +70,6 @@ #include <net/mac80211.h> #include <net/netlink.h> -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-debug.h" @@ -78,7 +77,15 @@ #include "iwl-agn.h" #include "iwl-testmode.h" #include "iwl-trans.h" -#include "iwl-bus.h" +#include "iwl-fh.h" +#include "iwl-prph.h" + + +/* Periphery registers absolute lower bound. This is used in order to + * differentiate registery access through HBUS_TARG_PRPH_* and + * HBUS_TARG_MEM_* accesses. + */ +#define IWL_TM_ABS_PRPH_START (0xA00000) /* The TLVs used in the gnl message policy between the kernel module and * user space application. iwl_testmode_gnl_msg_policy is to be carried @@ -109,19 +116,24 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, }, - [IWL_TM_ATTR_SRAM_ADDR] = { .type = NLA_U32, }, - [IWL_TM_ATTR_SRAM_SIZE] = { .type = NLA_U32, }, - [IWL_TM_ATTR_SRAM_DUMP] = { .type = NLA_UNSPEC, }, + [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, }, + [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, }, [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, }, [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, + + [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, }, }; /* * See the struct iwl_rx_packet in iwl-commands.h for the format of the * received events from the device */ -static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) +static inline int get_event_length(struct iwl_rx_cmd_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); if (pkt) @@ -152,7 +164,7 @@ static inline int get_event_length(struct iwl_rx_mem_buffer *rxb) */ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) + struct iwl_rx_cmd_buffer *rxb) { struct ieee80211_hw *hw = priv->hw; struct sk_buff *skb; @@ -168,35 +180,36 @@ static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv, skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length, GFP_ATOMIC); if (skb == NULL) { - IWL_DEBUG_INFO(priv, + IWL_ERR(priv, "Run out of memory for messages to user space ?\n"); return; } NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); - NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data); + /* the length doesn't include len_n_flags field, so add it manually */ + NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length + sizeof(__le32), data); cfg80211_testmode_event(skb, GFP_ATOMIC); return; nla_put_failure: kfree_skb(skb); - IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n"); + IWL_ERR(priv, "Ouch, overran buffer, check allocation!\n"); } void iwl_testmode_init(struct iwl_priv *priv) { - priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + priv->pre_rx_handler = NULL; priv->testmode_trace.trace_enabled = false; - priv->testmode_sram.sram_readed = false; + priv->testmode_mem.read_in_progress = false; } -static void iwl_sram_cleanup(struct iwl_priv *priv) +static void iwl_mem_cleanup(struct iwl_priv *priv) { - if (priv->testmode_sram.sram_readed) { - kfree(priv->testmode_sram.buff_addr); - priv->testmode_sram.buff_addr = NULL; - priv->testmode_sram.buff_size = 0; - priv->testmode_sram.num_chunks = 0; - priv->testmode_sram.sram_readed = false; + if (priv->testmode_mem.read_in_progress) { + kfree(priv->testmode_mem.buff_addr); + priv->testmode_mem.buff_addr = NULL; + priv->testmode_mem.buff_size = 0; + priv->testmode_mem.num_chunks = 0; + priv->testmode_mem.read_in_progress = false; } } @@ -205,7 +218,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) if (priv->testmode_trace.trace_enabled) { if (priv->testmode_trace.cpu_addr && priv->testmode_trace.dma_addr) - dma_free_coherent(bus(priv)->dev, + dma_free_coherent(trans(priv)->dev, priv->testmode_trace.total_size, priv->testmode_trace.cpu_addr, priv->testmode_trace.dma_addr); @@ -222,9 +235,10 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) void iwl_testmode_cleanup(struct iwl_priv *priv) { iwl_trace_cleanup(priv); - iwl_sram_cleanup(priv); + iwl_mem_cleanup(priv); } + /* * This function handles the user application commands to the ucode. * @@ -233,35 +247,80 @@ void iwl_testmode_cleanup(struct iwl_priv *priv) * host command to the ucode. * * If any mandatory field is missing, -ENOMSG is replied to the user space - * application; otherwise, the actual execution result of the host command to - * ucode is replied. + * application; otherwise, waits for the host command to be sent and checks + * the return code. In case or error, it is returned, otherwise a reply is + * allocated and the reply RX packet + * is returned. * * @hw: ieee80211_hw object that represents the device * @tb: gnl message fields from the user space */ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_host_cmd cmd; + struct iwl_rx_packet *pkt; + struct sk_buff *skb; + void *reply_buf; + u32 reply_len; + int ret; + bool cmd_want_skb; memset(&cmd, 0, sizeof(struct iwl_host_cmd)); if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] || !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) { - IWL_DEBUG_INFO(priv, - "Error finding ucode command mandatory fields\n"); + IWL_ERR(priv, "Missing ucode command mandatory fields\n"); return -ENOMSG; } - cmd.flags = CMD_ON_DEMAND; + cmd.flags = CMD_ON_DEMAND | CMD_SYNC; + cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]); + if (cmd_want_skb) + cmd.flags |= CMD_WANT_SKB; + cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," + IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," " len %d\n", cmd.id, cmd.flags, cmd.len[0]); - /* ok, let's submit the command to ucode */ - return iwl_trans_send_cmd(trans(priv), &cmd); + + ret = iwl_dvm_send_cmd(priv, &cmd); + if (ret) { + IWL_ERR(priv, "Failed to send hcmd\n"); + return ret; + } + if (!cmd_want_skb) + return ret; + + /* Handling return of SKB to the user */ + pkt = cmd.resp_pkt; + if (!pkt) { + IWL_ERR(priv, "HCMD received a null response packet\n"); + return ret; + } + + reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20); + reply_buf = kmalloc(reply_len, GFP_KERNEL); + if (!skb || !reply_buf) { + kfree_skb(skb); + kfree(reply_buf); + return -ENOMEM; + } + + /* The reply is in a page, that we cannot send to user space. */ + memcpy(reply_buf, &(pkt->hdr), reply_len); + iwl_free_resp(&cmd); + + NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT); + NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf); + return cfg80211_testmode_reply(skb); + +nla_put_failure: + IWL_DEBUG_INFO(priv, "Failed creating NL attributes\n"); + return -ENOMSG; } @@ -284,84 +343,69 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) */ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) { - struct iwl_priv *priv = hw->priv; - u32 ofs, val32; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + u32 ofs, val32, cmd; u8 val8; struct sk_buff *skb; int status = 0; if (!tb[IWL_TM_ATTR_REG_OFFSET]) { - IWL_DEBUG_INFO(priv, "Error finding register offset\n"); + IWL_ERR(priv, "Missing register offset\n"); return -ENOMSG; } ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs); - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { + /* Allow access only to FH/CSR/HBUS in direct mode. + Since we don't have the upper bounds for the CSR and HBUS segments, + we will use only the upper bound of FH for sanity check. */ + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 || + cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 || + cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) && + (ofs >= FH_MEM_UPPER_BOUND)) { + IWL_ERR(priv, "offset out of segment (0x0 - 0x%x)\n", + FH_MEM_UPPER_BOUND); + return -EINVAL; + } + + switch (cmd) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - val32 = iwl_read32(bus(priv), ofs); + val32 = iwl_read_direct32(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); if (!skb) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32); status = cfg80211_testmode_reply(skb); if (status < 0) - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", status); + IWL_ERR(priv, "Error sending msg : %d\n", status); break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: if (!tb[IWL_TM_ATTR_REG_VALUE32]) { - IWL_DEBUG_INFO(priv, - "Error finding value to write\n"); + IWL_ERR(priv, "Missing value to write\n"); return -ENOMSG; } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write32(bus(priv), ofs, val32); + iwl_write_direct32(trans(priv), ofs, val32); } break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: if (!tb[IWL_TM_ATTR_REG_VALUE8]) { - IWL_DEBUG_INFO(priv, "Error finding value to write\n"); + IWL_ERR(priv, "Missing value to write\n"); return -ENOMSG; } else { val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); IWL_INFO(priv, "8bit value to write 0x%x\n", val8); - iwl_write8(bus(priv), ofs, val8); - } - break; - case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: - val32 = iwl_read_prph(bus(priv), ofs); - IWL_INFO(priv, "32bit value to read 0x%x\n", val32); - - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); - if (!skb) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); - return -ENOMEM; - } - NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32); - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", status); - break; - case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: - if (!tb[IWL_TM_ATTR_REG_VALUE32]) { - IWL_DEBUG_INFO(priv, - "Error finding value to write\n"); - return -ENOMSG; - } else { - val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); - IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write_prph(bus(priv), ofs, val32); + iwl_write8(trans(priv), ofs, val8); } break; default: - IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n"); + IWL_ERR(priv, "Unknown testmode register command ID\n"); return -ENOSYS; } @@ -378,24 +422,23 @@ static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) struct iwl_notification_wait calib_wait; int ret; - iwl_init_notification_wait(priv->shrd, &calib_wait, - CALIBRATION_COMPLETE_NOTIFICATION, - NULL, NULL); - ret = iwl_init_alive_start(trans(priv)); + iwl_init_notification_wait(&priv->notif_wait, &calib_wait, + CALIBRATION_COMPLETE_NOTIFICATION, + NULL, NULL); + ret = iwl_init_alive_start(priv); if (ret) { - IWL_DEBUG_INFO(priv, - "Error configuring init calibration: %d\n", ret); + IWL_ERR(priv, "Fail init calibration: %d\n", ret); goto cfg_init_calib_error; } - ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ); + ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ); if (ret) - IWL_DEBUG_INFO(priv, "Error detecting" + IWL_ERR(priv, "Error detecting" " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); return ret; cfg_init_calib_error: - iwl_remove_notification(priv->shrd, &calib_wait); + iwl_remove_notification(&priv->notif_wait, &calib_wait); return ret; } @@ -417,12 +460,13 @@ cfg_init_calib_error: */ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_trans *trans = trans(priv); struct sk_buff *skb; unsigned char *rsp_data_ptr = NULL; int status = 0, rsp_data_len = 0; - u32 devid; + u32 devid, inst_size = 0, data_size = 0; + const struct fw_img *img; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: @@ -431,8 +475,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, rsp_data_len + 20); if (!skb) { - IWL_DEBUG_INFO(priv, - "Error allocating memory\n"); + IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, @@ -441,47 +484,47 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) rsp_data_len, rsp_data_ptr); status = cfg80211_testmode_reply(skb); if (status < 0) - IWL_DEBUG_INFO(priv, "Error sending msg : %d\n", - status); + IWL_ERR(priv, "Error sending msg : %d\n", status); break; case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: - status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); + status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); if (status) - IWL_DEBUG_INFO(priv, - "Error loading init ucode: %d\n", status); + IWL_ERR(priv, "Error loading init ucode: %d\n", status); break; case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: iwl_testmode_cfg_init_calib(priv); + priv->ucode_loaded = false; iwl_trans_stop_device(trans); break; case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: - status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR); + status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); if (status) { - IWL_DEBUG_INFO(priv, + IWL_ERR(priv, "Error loading runtime ucode: %d\n", status); break; } status = iwl_alive_start(priv); if (status) - IWL_DEBUG_INFO(priv, + IWL_ERR(priv, "Error starting the device: %d\n", status); break; case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: iwl_scan_cancel_timeout(priv, 200); + priv->ucode_loaded = false; iwl_trans_stop_device(trans); - status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN); + status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); if (status) { - IWL_DEBUG_INFO(priv, + IWL_ERR(priv, "Error loading WOWLAN ucode: %d\n", status); break; } status = iwl_alive_start(priv); if (status) - IWL_DEBUG_INFO(priv, + IWL_ERR(priv, "Error starting the device: %d\n", status); break; @@ -490,8 +533,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, cfg(priv)->base_params->eeprom_size + 20); if (!skb) { - IWL_DEBUG_INFO(priv, - "Error allocating memory\n"); + IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, @@ -501,55 +543,75 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) priv->shrd->eeprom); status = cfg80211_testmode_reply(skb); if (status < 0) - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", - status); + IWL_ERR(priv, "Error sending msg : %d\n", + status); } else return -EFAULT; break; case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: if (!tb[IWL_TM_ATTR_FIXRATE]) { - IWL_DEBUG_INFO(priv, - "Error finding fixrate setting\n"); + IWL_ERR(priv, "Missing fixrate setting\n"); return -ENOMSG; } priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); break; case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: - IWL_INFO(priv, "uCode version raw: 0x%x\n", priv->ucode_ver); + IWL_INFO(priv, "uCode version raw: 0x%x\n", + priv->fw->ucode_ver); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); if (!skb) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } - NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, priv->ucode_ver); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, + priv->fw->ucode_ver); status = cfg80211_testmode_reply(skb); if (status < 0) - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", status); + IWL_ERR(priv, "Error sending msg : %d\n", status); break; case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: - devid = bus_get_hw_id(bus(priv)); + devid = trans(priv)->hw_id; IWL_INFO(priv, "hw version: 0x%x\n", devid); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); if (!skb) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + IWL_ERR(priv, "Memory allocation fail\n"); return -ENOMEM; } NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid); status = cfg80211_testmode_reply(skb); if (status < 0) - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", status); + IWL_ERR(priv, "Error sending msg : %d\n", status); + break; + + case IWL_TM_CMD_APP2DEV_GET_FW_INFO: + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); + if (!skb) { + IWL_ERR(priv, "Memory allocation fail\n"); + return -ENOMEM; + } + if (!priv->ucode_loaded) { + IWL_ERR(priv, "No uCode has not been loaded\n"); + return -EINVAL; + } else { + img = &priv->fw->img[priv->shrd->ucode_type]; + inst_size = img->sec[IWL_UCODE_SECTION_INST].len; + data_size = img->sec[IWL_UCODE_SECTION_DATA].len; + } + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size); + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_ERR(priv, "Error sending msg : %d\n", status); break; default: - IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); + IWL_ERR(priv, "Unknown testmode driver command ID\n"); return -ENOSYS; } return status; @@ -574,10 +636,10 @@ nla_put_failure: */ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct sk_buff *skb; int status = 0; - struct device *dev = bus(priv)->dev; + struct device *dev = trans(priv)->dev; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: @@ -612,8 +674,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, sizeof(priv->testmode_trace.dma_addr) + 20); if (!skb) { - IWL_DEBUG_INFO(priv, - "Error allocating memory\n"); + IWL_ERR(priv, "Memory allocation fail\n"); iwl_trace_cleanup(priv); return -ENOMEM; } @@ -622,9 +683,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) (u64 *)&priv->testmode_trace.dma_addr); status = cfg80211_testmode_reply(skb); if (status < 0) { - IWL_DEBUG_INFO(priv, - "Error sending msg : %d\n", - status); + IWL_ERR(priv, "Error sending msg : %d\n", status); } priv->testmode_trace.num_chunks = DIV_ROUND_UP(priv->testmode_trace.buff_size, @@ -635,7 +694,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) iwl_trace_cleanup(priv); break; default: - IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n"); + IWL_ERR(priv, "Unknown testmode mem command ID\n"); return -ENOSYS; } return status; @@ -648,11 +707,11 @@ nla_put_failure: return -EMSGSIZE; } -static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, +static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct sk_buff *skb, struct netlink_callback *cb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int idx, length; if (priv->testmode_trace.trace_enabled && @@ -696,24 +755,105 @@ static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb, */ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); u8 owner; if (!tb[IWL_TM_ATTR_UCODE_OWNER]) { - IWL_DEBUG_INFO(priv, "Error finding ucode owner\n"); + IWL_ERR(priv, "Missing ucode owner\n"); return -ENOMSG; } owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); - if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM)) - priv->shrd->ucode_owner = owner; - else { - IWL_DEBUG_INFO(priv, "Invalid owner\n"); + if (owner == IWL_OWNERSHIP_DRIVER) { + priv->ucode_owner = owner; + priv->pre_rx_handler = NULL; + } else if (owner == IWL_OWNERSHIP_TM) { + priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + priv->ucode_owner = owner; + } else { + IWL_ERR(priv, "Invalid owner\n"); return -EINVAL; } return 0; } +static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size) +{ + struct iwl_trans *trans = trans(priv); + unsigned long flags; + int i; + + if (size & 0x3) + return -EINVAL; + priv->testmode_mem.buff_size = size; + priv->testmode_mem.buff_addr = + kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL); + if (priv->testmode_mem.buff_addr == NULL) + return -ENOMEM; + + /* Hard-coded periphery absolute address */ + if (IWL_TM_ABS_PRPH_START <= addr && + addr < IWL_TM_ABS_PRPH_START + PRPH_END) { + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + iwl_write32(trans, HBUS_TARG_PRPH_RADDR, + addr | (3 << 24)); + for (i = 0; i < size; i += 4) + *(u32 *)(priv->testmode_mem.buff_addr + i) = + iwl_read32(trans, HBUS_TARG_PRPH_RDAT); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); + } else { /* target memory (SRAM) */ + _iwl_read_targ_mem_words(trans, addr, + priv->testmode_mem.buff_addr, + priv->testmode_mem.buff_size / 4); + } + + priv->testmode_mem.num_chunks = + DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE); + priv->testmode_mem.read_in_progress = true; + return 0; + +} + +static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr, + u32 size, unsigned char *buf) +{ + struct iwl_trans *trans = trans(priv); + u32 val, i; + unsigned long flags; + + if (IWL_TM_ABS_PRPH_START <= addr && + addr < IWL_TM_ABS_PRPH_START + PRPH_END) { + /* Periphery writes can be 1-3 bytes long, or DWORDs */ + if (size < 4) { + memcpy(&val, buf, size); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + iwl_write32(trans, HBUS_TARG_PRPH_WADDR, + (addr & 0x0000FFFF) | + ((size - 1) << 24)); + iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); + iwl_release_nic_access(trans); + /* needed after consecutive writes w/o read */ + mmiowb(); + spin_unlock_irqrestore(&trans->reg_lock, flags); + } else { + if (size % 4) + return -EINVAL; + for (i = 0; i < size; i += 4) + iwl_write_prph(trans, addr+i, + *(u32 *)(buf+i)); + } + } else if (iwlagn_hw_valid_rtc_data_addr(addr) || + (IWLAGN_RTC_INST_LOWER_BOUND <= addr && + addr < IWLAGN_RTC_INST_UPPER_BOUND)) { + _iwl_write_targ_mem_words(trans, addr, buf, size/4); + } else + return -EINVAL; + return 0; +} + /* * This function handles the user application commands for SRAM data dump * @@ -730,83 +870,60 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) * @hw: ieee80211_hw object that represents the device * @tb: gnl message fields from the user space */ -static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) +static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw, + struct nlattr **tb) { - struct iwl_priv *priv = hw->priv; - u32 base, ofs, size, maxsize; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + u32 addr, size, cmd; + unsigned char *buf; - if (priv->testmode_sram.sram_readed) + /* Both read and write should be blocked, for atomicity */ + if (priv->testmode_mem.read_in_progress) return -EBUSY; - if (!tb[IWL_TM_ATTR_SRAM_ADDR]) { - IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n"); + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + if (!tb[IWL_TM_ATTR_MEM_ADDR]) { + IWL_ERR(priv, "Error finding memory offset address\n"); return -ENOMSG; } - ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]); - if (!tb[IWL_TM_ATTR_SRAM_SIZE]) { - IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n"); + addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]); + if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) { + IWL_ERR(priv, "Error finding size for memory reading\n"); return -ENOMSG; } - size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]); - switch (priv->shrd->ucode_type) { - case IWL_UCODE_REGULAR: - maxsize = trans(priv)->ucode_rt.data.len; - break; - case IWL_UCODE_INIT: - maxsize = trans(priv)->ucode_init.data.len; - break; - case IWL_UCODE_WOWLAN: - maxsize = trans(priv)->ucode_wowlan.data.len; - break; - case IWL_UCODE_NONE: - IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n"); - return -ENOSYS; - default: - IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n"); - return -ENOSYS; - } - if ((ofs + size) > maxsize) { - IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n"); - return -EINVAL; - } - priv->testmode_sram.buff_size = (size / 4) * 4; - priv->testmode_sram.buff_addr = - kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL); - if (priv->testmode_sram.buff_addr == NULL) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); - return -ENOMEM; + size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]); + + if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) + return iwl_testmode_indirect_read(priv, addr, size); + else { + if (!tb[IWL_TM_ATTR_BUFFER_DUMP]) + return -EINVAL; + buf = (unsigned char *) nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]); + return iwl_testmode_indirect_write(priv, addr, size, buf); } - base = 0x800000; - _iwl_read_targ_mem_words(bus(priv), base + ofs, - priv->testmode_sram.buff_addr, - priv->testmode_sram.buff_size / 4); - priv->testmode_sram.num_chunks = - DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE); - priv->testmode_sram.sram_readed = true; - return 0; } -static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb, - struct sk_buff *skb, - struct netlink_callback *cb) +static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct netlink_callback *cb) { - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int idx, length; - if (priv->testmode_sram.sram_readed) { + if (priv->testmode_mem.read_in_progress) { idx = cb->args[4]; - if (idx >= priv->testmode_sram.num_chunks) { - iwl_sram_cleanup(priv); + if (idx >= priv->testmode_mem.num_chunks) { + iwl_mem_cleanup(priv); return -ENOENT; } length = DUMP_CHUNK_SIZE; - if (((idx + 1) == priv->testmode_sram.num_chunks) && - (priv->testmode_sram.buff_size % DUMP_CHUNK_SIZE)) - length = priv->testmode_sram.buff_size % + if (((idx + 1) == priv->testmode_mem.num_chunks) && + (priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE)) + length = priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE; - NLA_PUT(skb, IWL_TM_ATTR_SRAM_DUMP, length, - priv->testmode_sram.buff_addr + + NLA_PUT(skb, IWL_TM_ATTR_BUFFER_DUMP, length, + priv->testmode_mem.buff_addr + (DUMP_CHUNK_SIZE * idx)); idx++; cb->args[4] = idx; @@ -818,6 +935,20 @@ static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb, return -ENOBUFS; } +static int iwl_testmode_notifications(struct ieee80211_hw *hw, + struct nlattr **tb) +{ + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); + bool enable; + + enable = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]); + if (enable) + priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; + else + priv->pre_rx_handler = NULL; + return 0; +} + /* 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 @@ -841,24 +972,23 @@ static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb, int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) { struct nlattr *tb[IWL_TM_ATTR_MAX]; - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int result; result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len, iwl_testmode_gnl_msg_policy); if (result != 0) { - IWL_DEBUG_INFO(priv, - "Error parsing the gnl message : %d\n", result); + IWL_ERR(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"); + IWL_ERR(priv, "Missing testmode command type\n"); return -ENOMSG; } /* in case multiple accesses to the device happens */ - mutex_lock(&priv->shrd->mutex); + mutex_lock(&priv->mutex); switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_UCODE: @@ -868,8 +998,6 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: - case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: - case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: IWL_DEBUG_INFO(priv, "testmode cmd to register\n"); result = iwl_testmode_reg(hw, tb); break; @@ -882,6 +1010,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: + case IWL_TM_CMD_APP2DEV_GET_FW_INFO: IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; @@ -898,18 +1027,26 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) result = iwl_testmode_ownership(hw, tb); break; - case IWL_TM_CMD_APP2DEV_READ_SRAM: - IWL_DEBUG_INFO(priv, "testmode sram read cmd to driver\n"); - result = iwl_testmode_sram(hw, tb); + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: + IWL_DEBUG_INFO(priv, "testmode indirect memory cmd " + "to driver\n"); + result = iwl_testmode_indirect_mem(hw, tb); + break; + + case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: + IWL_DEBUG_INFO(priv, "testmode notifications cmd " + "to driver\n"); + result = iwl_testmode_notifications(hw, tb); break; default: - IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); + IWL_ERR(priv, "Unknown testmode command\n"); result = -ENOSYS; break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return result; } @@ -918,7 +1055,7 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, void *data, int len) { struct nlattr *tb[IWL_TM_ATTR_MAX]; - struct iwl_priv *priv = hw->priv; + struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); int result; u32 cmd; @@ -929,15 +1066,14 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, 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); + IWL_ERR(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"); + IWL_ERR(priv, "Missing testmode command type\n"); return -ENOMSG; } cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); @@ -945,21 +1081,21 @@ int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, } /* in case multiple accesses to the device happens */ - mutex_lock(&priv->shrd->mutex); + 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); + result = iwl_testmode_trace_dump(hw, skb, cb); break; - case IWL_TM_CMD_APP2DEV_DUMP_SRAM: + case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n"); - result = iwl_testmode_sram_dump(hw, tb, skb, cb); + result = iwl_testmode_buffer_dump(hw, skb, cb); break; default: result = -EINVAL; break; } - mutex_unlock(&priv->shrd->mutex); + mutex_unlock(&priv->mutex); return result; } diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 26138f11034..6ba211b0942 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ * to user application * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT: * commands from kernel space to multicast the spontaneous messages - * to user application + * to user application, or reply of host commands * @IWL_TM_CMD_DEV2APP_EEPROM_RSP: * commands from kernel space to carry the eeprom response * to user application @@ -109,18 +109,22 @@ * if application has the ownership, the only host command from * testmode will deliver to uCode. Default owner is driver * - * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: - * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: - * commands from user applicaiton to indirectly access peripheral register - * - * @IWL_TM_CMD_APP2DEV_READ_SRAM: - * @IWL_TM_CMD_APP2DEV_DUMP_SRAM: - * commands from user applicaiton to read data in sram - * - * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image + * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device - * + * @IWL_TM_CMD_APP2DEV_GET_FW_INFO: + * retrieve information of existing loaded uCode image + * + * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: + * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP: + * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: + * Commands to read/write data from periphery or SRAM memory ranges. + * Fore reading, a READ command is sent from the userspace and the data + * is returned when the user calls a DUMP command. + * For writing, only a WRITE command is used. + * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS: + * Command to enable/disable notifications (currently RX packets) from the + * driver to userspace. */ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_UCODE = 1, @@ -140,14 +144,19 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15, IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16, IWL_TM_CMD_APP2DEV_OWNERSHIP = 17, - IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32 = 18, - IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32 = 19, - IWL_TM_CMD_APP2DEV_READ_SRAM = 20, - IWL_TM_CMD_APP2DEV_DUMP_SRAM = 21, + RESERVED_18 = 18, + RESERVED_19 = 19, + RESERVED_20 = 20, + RESERVED_21 = 21, IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22, IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23, IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24, - IWL_TM_CMD_MAX = 25, + IWL_TM_CMD_APP2DEV_GET_FW_INFO = 25, + IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26, + IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27, + IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28, + IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29, + IWL_TM_CMD_MAX = 30, }; /* @@ -168,8 +177,6 @@ enum iwl_tm_cmd_t { * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE, * The mandatory fields are : * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID; - * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands; - * The optional fields are: * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload * to the ucode * @@ -218,16 +225,19 @@ enum iwl_tm_cmd_t { * The mandatory fields are: * IWL_TM_ATTR_UCODE_OWNER for the new owner * - * @IWL_TM_ATTR_SRAM_ADDR: - * @IWL_TM_ATTR_SRAM_SIZE: - * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_READ_SRAM, + * @IWL_TM_ATTR_MEM_ADDR: + * @IWL_TM_ATTR_BUFFER_SIZE: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ + * or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE. * The mandatory fields are: - * IWL_TM_ATTR_SRAM_ADDR for the address in sram - * IWL_TM_ATTR_SRAM_SIZE for the buffer size of data reading + * IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write + * IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write. * - * @IWL_TM_ATTR_SRAM_DUMP: - * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_DUMP_SRAM, - * IWL_TM_ATTR_SRAM_DUMP for the data in sram + * @IWL_TM_ATTR_BUFFER_DUMP: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP, + * IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read. + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE, + * this attribute contains the data to write. * * @IWL_TM_ATTR_FW_VERSION: * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION, @@ -237,6 +247,23 @@ enum iwl_tm_cmd_t { * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID, * IWL_TM_ATTR_DEVICE_ID for the device ID information * + * @IWL_TM_ATTR_FW_TYPE: + * @IWL_TM_ATTR_FW_INST_SIZE: + * @IWL_TM_ATTR_FW_DATA_SIZE: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO, + * The mandatory fields are: + * IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...) + * IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section + * IWL_TM_ATTR_FW_DATA_SIZE for the size of data section + * + * @IWL_TM_ATTR_UCODE_CMD_SKB: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag + * indicates that the user wants to receive the response of the command + * in a reply SKB. If it's not present, the response is not returned. + * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this + * flag enables (if present) or disables (if not) the forwarding + * to userspace. */ enum iwl_tm_attr_t { IWL_TM_ATTR_NOT_APPLICABLE = 0, @@ -254,12 +281,17 @@ enum iwl_tm_attr_t { IWL_TM_ATTR_TRACE_DUMP = 12, IWL_TM_ATTR_FIXRATE = 13, IWL_TM_ATTR_UCODE_OWNER = 14, - IWL_TM_ATTR_SRAM_ADDR = 15, - IWL_TM_ATTR_SRAM_SIZE = 16, - IWL_TM_ATTR_SRAM_DUMP = 17, + IWL_TM_ATTR_MEM_ADDR = 15, + IWL_TM_ATTR_BUFFER_SIZE = 16, + IWL_TM_ATTR_BUFFER_DUMP = 17, IWL_TM_ATTR_FW_VERSION = 18, IWL_TM_ATTR_DEVICE_ID = 19, - IWL_TM_ATTR_MAX = 20, + IWL_TM_ATTR_FW_TYPE = 20, + IWL_TM_ATTR_FW_INST_SIZE = 21, + IWL_TM_ATTR_FW_DATA_SIZE = 22, + IWL_TM_ATTR_UCODE_CMD_SKB = 23, + IWL_TM_ATTR_ENABLE_NOTIFICATION = 24, + IWL_TM_ATTR_MAX = 25, }; /* uCode trace buffer */ @@ -271,4 +303,7 @@ enum iwl_tm_attr_t { /* Maximum data size of each dump it packet */ #define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024) +/* Address offset of data segment in SRAM */ +#define SRAM_DATA_SEG_OFFSET 0x800000 + #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index f6debf91d7b..1c2fe87bd7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -32,6 +32,7 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/skbuff.h> +#include <linux/wait.h> #include <linux/pci.h> #include "iwl-fh.h" @@ -40,6 +41,7 @@ #include "iwl-trans.h" #include "iwl-debug.h" #include "iwl-io.h" +#include "iwl-op-mode.h" struct iwl_tx_queue; struct iwl_queue; @@ -48,6 +50,12 @@ struct iwl_host_cmd; /*This file includes the declaration that are internal to the * trans_pcie layer */ +struct iwl_rx_mem_buffer { + dma_addr_t page_dma; + struct page *page; + struct list_head list; +}; + /** * struct isr_statistics - interrupt statistics * @@ -108,6 +116,26 @@ struct iwl_dma_ptr { size_t size; }; +/** + * iwl_queue_inc_wrap - increment queue index, wrap back to beginning + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_queue_inc_wrap(int index, int n_bd) +{ + return ++index & (n_bd - 1); +} + +/** + * iwl_queue_dec_wrap - decrement queue index, wrap back to end + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl_queue_dec_wrap(int index, int n_bd) +{ + return --index & (n_bd - 1); +} + /* * This queue number is required for proper operation * because the ucode will stop/start the scheduler as @@ -168,6 +196,7 @@ struct iwl_queue { * @meta: array of meta data for each command/tx buffer * @dma_addr_cmd: physical address of cmd/tx buffer array * @txb: array of per-TFD driver data + * lock: queue lock * @time_stamp: time (in jiffies) of last read_ptr change * @need_update: indicates need to update read/write index * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled @@ -186,6 +215,7 @@ struct iwl_tx_queue { struct iwl_device_cmd **cmd; struct iwl_cmd_meta *meta; struct sk_buff **skbs; + spinlock_t lock; unsigned long time_stamp; u8 need_update; u8 sched_retry; @@ -201,6 +231,8 @@ struct iwl_tx_queue { * @rxq: all the RX queue data * @rx_replenish: work that will be called when buffers need to be allocated * @trans: pointer to the generic transport area + * @irq - the irq number for the device + * @irq_requested: true when the irq has been requested * @scd_base_addr: scheduler sram base address in SRAM * @scd_bc_tbls: pointer to the byte count table of the scheduler * @kw: keep warm address @@ -211,6 +243,12 @@ struct iwl_tx_queue { * @txq_ctx_active_msk: what queue is active * queue_stopped: tracks what queue is stopped * queue_stop_count: tracks what SW queue is stopped + * @pci_dev: basic pci-network driver stuff + * @hw_base: pci hardware address support + * @ucode_write_complete: indicates that the ucode has been copied. + * @ucode_write_waitq: wait queue for uCode load + * @status - transport specific status flags + * @cmd_queue - command queue number */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -223,9 +261,12 @@ struct iwl_trans_pcie { int ict_index; u32 inta; bool use_ict; + bool irq_requested; struct tasklet_struct irq_tasklet; struct isr_statistics isr_stats; + unsigned int irq; + spinlock_t irq_lock; u32 inta_mask; u32 scd_base_addr; struct iwl_dma_ptr scd_bc_tbls; @@ -241,6 +282,17 @@ struct iwl_trans_pcie { #define IWL_MAX_HW_QUEUES 32 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; atomic_t queue_stop_count[4]; + + /* PCI bus related data */ + struct pci_dev *pci_dev; + void __iomem *hw_base; + + bool ucode_write_complete; + wait_queue_head_t ucode_write_waitq; + unsigned long status; + u8 cmd_queue; + u8 n_no_reclaim_cmds; + u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ @@ -258,7 +310,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, /***************************************************** * ICT ******************************************************/ -int iwl_reset_ict(struct iwl_trans *trans); +void iwl_reset_ict(struct iwl_trans *trans); void iwl_disable_ict(struct iwl_trans *trans); int iwl_alloc_isr_ict(struct iwl_trans *trans); void iwl_free_isr_ict(struct iwl_trans *trans); @@ -275,7 +327,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); void iwl_tx_cmd_complete(struct iwl_trans *trans, - struct iwl_rx_mem_buffer *rxb, int handler_status); + struct iwl_rx_cmd_buffer *rxb, int handler_status); void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_tx_queue *txq, u16 byte_cnt); @@ -308,26 +360,32 @@ void iwl_dump_csr(struct iwl_trans *trans); ******************************************************/ static inline void iwl_disable_interrupts(struct iwl_trans *trans) { - clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); /* disable interrupts from uCode/NIC to host */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* acknowledge/clear/reset any interrupts still pending * from uCode or flow handler (Rx/Tx DMA) */ - iwl_write32(bus(trans), CSR_INT, 0xffffffff); - iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff); + iwl_write32(trans, CSR_INT, 0xffffffff); + iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff); IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); } static inline void iwl_enable_interrupts(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); - set_bit(STATUS_INT_ENABLED, &trans->shrd->status); - iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask); + set_bit(STATUS_INT_ENABLED, &trans_pcie->status); + iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); +} + +static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) +{ + IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); + iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); } /* @@ -355,7 +413,7 @@ static inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq) } static inline void iwl_wake_queue(struct iwl_trans *trans, - struct iwl_tx_queue *txq, const char *msg) + struct iwl_tx_queue *txq) { u8 queue = txq->swq_id; u8 ac = queue & 3; @@ -365,20 +423,20 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { - iwl_wake_sw_queue(priv(trans), ac); - IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", - hwq, ac, msg); + iwl_op_mode_queue_not_full(trans->op_mode, ac); + IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d", + hwq, ac); } else { - IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" - " stop count %d. %s", - hwq, ac, atomic_read(&trans_pcie-> - queue_stop_count[ac]), msg); + IWL_DEBUG_TX_QUEUES(trans, + "Don't wake hwq %d ac %d stop count %d", + hwq, ac, + atomic_read(&trans_pcie->queue_stop_count[ac])); } } } static inline void iwl_stop_queue(struct iwl_trans *trans, - struct iwl_tx_queue *txq, const char *msg) + struct iwl_tx_queue *txq) { u8 queue = txq->swq_id; u8 ac = queue & 3; @@ -388,35 +446,23 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { - iwl_stop_sw_queue(priv(trans), ac); - IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" - " stop count %d. %s", - hwq, ac, atomic_read(&trans_pcie-> - queue_stop_count[ac]), msg); + iwl_op_mode_queue_full(trans->op_mode, ac); + IWL_DEBUG_TX_QUEUES(trans, + "Stop hwq %d ac %d stop count %d", + hwq, ac, + atomic_read(&trans_pcie->queue_stop_count[ac])); } else { - IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" - " stop count %d. %s", - hwq, ac, atomic_read(&trans_pcie-> - queue_stop_count[ac]), msg); + IWL_DEBUG_TX_QUEUES(trans, + "Don't stop hwq %d ac %d stop count %d", + hwq, ac, + atomic_read(&trans_pcie->queue_stop_count[ac])); } } else { - IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", - hwq, msg); + IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped", + hwq); } } -#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_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, int txq_id) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 65d1f05007b..8b1a7988e17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -30,10 +30,14 @@ #include <linux/wait.h> #include <linux/gfp.h> -/*TODO: Remove include to iwl-core.h*/ -#include "iwl-core.h" +#include "iwl-prph.h" #include "iwl-io.h" #include "iwl-trans-pcie-int.h" +#include "iwl-op-mode.h" + +#ifdef CONFIG_IWLWIFI_IDI +#include "iwl-amfh.h" +#endif /****************************************************************************** * @@ -136,34 +140,34 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, if (q->need_update == 0) goto exit_unlock; - if (hw_params(trans).shadow_reg_enable) { + if (cfg(trans)->base_params->shadow_reg_enable) { /* shadow register enabled */ /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write32(bus(trans), FH_RSCSR_CHNL0_WPTR, q->write_actual); + iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); } else { /* If power-saving is in use, make sure device is awake */ if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) { - reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); + reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup," " GP1 = 0x%x\n", reg); - iwl_set_bit(bus(trans), CSR_GP_CNTRL, + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); goto exit_unlock; } q->write_actual = (q->write & ~0x7); - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); /* Else device is assumed to be awake */ } else { /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); } } @@ -223,7 +227,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans) /* If the pre-allocated buffer pool is dropping low, schedule to * refill it */ if (rxq->free_count <= RX_LOW_WATERMARK) - queue_work(trans->shrd->workqueue, &trans_pcie->rx_replenish); + schedule_work(&trans_pcie->rx_replenish); /* If we've added more space for the firmware to place data, tell it. @@ -308,7 +312,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) BUG_ON(rxb->page); rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = dma_map_page(bus(trans)->dev, page, 0, + rxb->page_dma = dma_map_page(trans->dev, page, 0, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); /* dma address must be no more than 36 bits */ @@ -327,13 +331,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) void iwlagn_rx_replenish(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); unsigned long flags; iwlagn_rx_allocate(trans, GFP_KERNEL); - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); iwlagn_rx_queue_restock(trans); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } static void iwlagn_rx_replenish_now(struct iwl_trans *trans) @@ -347,14 +352,108 @@ void iwl_bg_rx_replenish(struct work_struct *data) { struct iwl_trans_pcie *trans_pcie = container_of(data, struct iwl_trans_pcie, rx_replenish); - struct iwl_trans *trans = trans_pcie->trans; - if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) + iwlagn_rx_replenish(trans_pcie->trans); +} + +static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; + struct iwl_device_cmd *cmd; + unsigned long flags; + int len, err; + u16 sequence; + struct iwl_rx_cmd_buffer rxcb; + struct iwl_rx_packet *pkt; + bool reclaim; + int index, cmd_index; + + if (WARN_ON(!rxb)) return; - mutex_lock(&trans->shrd->mutex); - iwlagn_rx_replenish(trans); - mutex_unlock(&trans->shrd->mutex); + dma_unmap_page(trans->dev, rxb->page_dma, + PAGE_SIZE << hw_params(trans).rx_page_order, + DMA_FROM_DEVICE); + + rxcb._page = rxb->page; + pkt = rxb_addr(&rxcb); + + IWL_DEBUG_RX(trans, "%s, 0x%02x\n", + get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + + + len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; + len += sizeof(u32); /* account for status word */ + trace_iwlwifi_dev_rx(trans->dev, pkt, len); + + /* Reclaim a command buffer only if this packet is a response + * to a (driver-originated) command. + * If the packet (e.g. Rx frame) originated from uCode, + * there is no command buffer to reclaim. + * Ucode should set SEQ_RX_FRAME bit if ucode-originated, + * but apparently a few don't get set; catch them here. */ + reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME); + if (reclaim) { + int i; + + for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) { + if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) { + reclaim = false; + break; + } + } + } + + sequence = le16_to_cpu(pkt->hdr.sequence); + index = SEQ_TO_INDEX(sequence); + cmd_index = get_cmd_index(&txq->q, index); + + if (reclaim) + cmd = txq->cmd[cmd_index]; + else + cmd = NULL; + + err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); + + /* + * XXX: After here, we should always check rxcb._page + * against NULL before touching it or its virtual + * memory (pkt). Because some rx_handler might have + * already taken or freed the pages. + */ + + if (reclaim) { + /* Invoke any callbacks, transfer the buffer to caller, + * and fire off the (possibly) blocking + * iwl_trans_send_cmd() + * as we reclaim the driver command queue */ + if (rxcb._page) + iwl_tx_cmd_complete(trans, &rxcb, err); + else + IWL_WARN(trans, "Claim null rxb?\n"); + } + + /* page was stolen from us */ + if (rxcb._page == NULL) + rxb->page = NULL; + + /* Reuse the page if possible. For notification packets and + * SKBs that fail to Rx correctly, add them back into the + * rx_free list for reuse later. */ + spin_lock_irqsave(&rxq->lock, flags); + if (rxb->page != NULL) { + rxb->page_dma = + dma_map_page(trans->dev, rxb->page, 0, + PAGE_SIZE << hw_params(trans).rx_page_order, + DMA_FROM_DEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } else + list_add_tail(&rxb->list, &rxq->rx_used); + spin_unlock_irqrestore(&rxq->lock, flags); } /** @@ -366,20 +465,12 @@ void iwl_bg_rx_replenish(struct work_struct *data) */ static void iwl_rx_handle(struct iwl_trans *trans) { - struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_packet *pkt; - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; - struct iwl_device_cmd *cmd; u32 r, i; - int reclaim; - unsigned long flags; u8 fill_rx = 0; u32 count = 8; int total_empty; - int index, cmd_index; /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ @@ -399,102 +490,14 @@ static void iwl_rx_handle(struct iwl_trans *trans) fill_rx = 1; while (i != r) { - int len, err; - u16 sequence; + struct iwl_rx_mem_buffer *rxb; rxb = rxq->queue[i]; - - /* If an RXB doesn't have a Rx queue slot associated with it, - * then a bug has been introduced in the queue refilling - * routines -- catch it here */ - if (WARN_ON(rxb == NULL)) { - i = (i + 1) & RX_QUEUE_MASK; - continue; - } - rxq->queue[i] = NULL; - dma_unmap_page(bus(trans)->dev, rxb->page_dma, - PAGE_SIZE << hw_params(trans).rx_page_order, - DMA_FROM_DEVICE); - pkt = rxb_addr(rxb); - - IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r, - i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); - - len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - len += sizeof(u32); /* account for status word */ - trace_iwlwifi_dev_rx(priv(trans), pkt, len); - - /* Reclaim a command buffer only if this packet is a response - * to a (driver-originated) command. - * If the packet (e.g. Rx frame) originated from uCode, - * there is no command buffer to reclaim. - * Ucode should set SEQ_RX_FRAME bit if ucode-originated, - * but apparently a few don't get set; catch them here. */ - reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) && - (pkt->hdr.cmd != REPLY_RX_PHY_CMD) && - (pkt->hdr.cmd != REPLY_RX) && - (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) && - (pkt->hdr.cmd != REPLY_COMPRESSED_BA) && - (pkt->hdr.cmd != STATISTICS_NOTIFICATION) && - (pkt->hdr.cmd != REPLY_TX); - - sequence = le16_to_cpu(pkt->hdr.sequence); - index = SEQ_TO_INDEX(sequence); - cmd_index = get_cmd_index(&txq->q, index); - - if (reclaim) - cmd = txq->cmd[cmd_index]; - else - cmd = NULL; - - /* warn if this is cmd response / notification and the uCode - * didn't set the SEQ_RX_FRAME for a frame that is - * uCode-originated - * If you saw this code after the second half of 2012, then - * please remove it - */ - WARN(pkt->hdr.cmd != REPLY_TX && reclaim == false && - (!(pkt->hdr.sequence & SEQ_RX_FRAME)), - "reclaim is false, SEQ_RX_FRAME unset: %s\n", - get_cmd_string(pkt->hdr.cmd)); - - err = iwl_rx_dispatch(priv(trans), rxb, cmd); - - /* - * XXX: After here, we should always check rxb->page - * against NULL before touching it or its virtual - * memory (pkt). Because some rx_handler might have - * already taken or freed the pages. - */ - - if (reclaim) { - /* Invoke any callbacks, transfer the buffer to caller, - * and fire off the (possibly) blocking - * iwl_trans_send_cmd() - * as we reclaim the driver command queue */ - if (rxb->page) - iwl_tx_cmd_complete(trans, rxb, err); - else - IWL_WARN(trans, "Claim null rxb?\n"); - } - - /* Reuse the page if possible. For notification packets and - * SKBs that fail to Rx correctly, add them back into the - * rx_free list for reuse later. */ - spin_lock_irqsave(&rxq->lock, flags); - if (rxb->page != NULL) { - rxb->page_dma = dma_map_page(bus(trans)->dev, rxb->page, - 0, PAGE_SIZE << - hw_params(trans).rx_page_order, - DMA_FROM_DEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } else - list_add_tail(&rxb->list, &rxq->rx_used); + IWL_DEBUG_RX(trans, "rxbuf: r = %d, i = %d (%p)\n", rxb); - spin_unlock_irqrestore(&rxq->lock, flags); + iwl_rx_handle_rxbuf(trans, rxb); i = (i + 1) & RX_QUEUE_MASK; /* If there are a lot of unused frames, @@ -590,17 +593,16 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) { u32 base; struct iwl_error_event_table table; - struct iwl_priv *priv = priv(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); base = trans->shrd->device_pointers.error_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { if (!base) - base = priv->init_errlog_ptr; + base = trans->shrd->fw->init_errlog_ptr; } else { if (!base) - base = priv->inst_errlog_ptr; + base = trans->shrd->fw->inst_errlog_ptr; } if (!iwlagn_hw_valid_rtc_data_addr(base)) { @@ -612,7 +614,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) return; } - iwl_read_targ_mem_words(bus(priv), base, &table, sizeof(table)); + iwl_read_targ_mem_words(trans, base, &table, sizeof(table)); if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { IWL_ERR(trans, "Start IWL Error Log Dump:\n"); @@ -622,7 +624,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) trans_pcie->isr_stats.err_code = table.error_id; - trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low, + trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low, table.data1, table.data2, table.line, table.blink1, table.blink2, table.ilink1, table.ilink2, table.bcon_time, table.gp1, @@ -670,12 +672,11 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) */ static void iwl_irq_handle_error(struct iwl_trans *trans) { - struct iwl_priv *priv = priv(trans); /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ - if (cfg(priv)->internal_wimax_coex && - (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) & + if (cfg(trans)->internal_wimax_coex && + (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & APMS_CLK_VAL_MRB_FUNC_MODE) || - (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) & + (iwl_read_prph(trans, APMG_PS_CTRL_REG) & APMG_PS_CTRL_VAL_RESET_REQ))) { /* * Keep the restart process from trying to send host @@ -683,24 +684,20 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) */ clear_bit(STATUS_READY, &trans->shrd->status); clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - wake_up(&priv->shrd->wait_command_queue); + wake_up(&trans->wait_command_queue); IWL_ERR(trans, "RF is used by WiMAX\n"); return; } IWL_ERR(trans, "Loaded firmware version: %s\n", - priv->hw->wiphy->fw_version); + trans->shrd->fw->fw_version); iwl_dump_nic_error_log(trans); iwl_dump_csr(trans); iwl_dump_fh(trans, NULL, false); iwl_dump_nic_event_log(trans, false, NULL, false); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) - iwl_print_rx_config_cmd(priv(trans), IWL_RXON_CTX_BSS); -#endif - iwlagn_fw_error(priv, false); + iwl_op_mode_nic_error(trans->op_mode); } #define EVENT_START_OFFSET (4 * sizeof(u32)) @@ -719,7 +716,6 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, u32 ptr; /* SRAM byte address of log data */ u32 ev, time, data; /* event log data */ unsigned long reg_flags; - struct iwl_priv *priv = priv(trans); if (num_events == 0) return pos; @@ -727,10 +723,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, base = trans->shrd->device_pointers.log_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { if (!base) - base = priv->init_evtlog_ptr; + base = trans->shrd->fw->init_evtlog_ptr; } else { if (!base) - base = priv->inst_evtlog_ptr; + base = trans->shrd->fw->inst_evtlog_ptr; } if (mode == 0) @@ -741,18 +737,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ptr = base + EVENT_START_OFFSET + (start_idx * event_size); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags); - iwl_grab_nic_access(bus(trans)); + spin_lock_irqsave(&trans->reg_lock, reg_flags); + if (unlikely(!iwl_grab_nic_access(trans))) + goto out_unlock; /* Set starting address; reads will auto-increment */ - iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr); - rmb(); + iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); /* "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_read32(bus(trans), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + time = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (mode == 0) { /* data, ev */ if (bufsz) { @@ -760,13 +756,13 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, "EVT_LOG:0x%08x:%04u\n", time, ev); } else { - trace_iwlwifi_dev_ucode_event(priv, 0, + trace_iwlwifi_dev_ucode_event(trans->dev, 0, time, ev); IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n", time, ev); } } else { - data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + data = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", @@ -774,15 +770,16 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, } else { IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n", time, data, ev); - trace_iwlwifi_dev_ucode_event(priv, time, + trace_iwlwifi_dev_ucode_event(trans->dev, time, data, ev); } } } /* Allow device to power down */ - iwl_release_nic_access(bus(trans)); - spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags); + iwl_release_nic_access(trans); +out_unlock: + spin_unlock_irqrestore(&trans->reg_lock, reg_flags); return pos; } @@ -836,17 +833,16 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, u32 logsize; int pos = 0; size_t bufsz = 0; - struct iwl_priv *priv = priv(trans); base = trans->shrd->device_pointers.log_event_table; if (trans->shrd->ucode_type == IWL_UCODE_INIT) { - logsize = priv->init_evtlog_size; + logsize = trans->shrd->fw->init_evtlog_size; if (!base) - base = priv->init_evtlog_ptr; + base = trans->shrd->fw->init_evtlog_ptr; } else { - logsize = priv->inst_evtlog_size; + logsize = trans->shrd->fw->inst_evtlog_size; if (!base) - base = priv->inst_evtlog_ptr; + base = trans->shrd->fw->inst_evtlog_ptr; } if (!iwlagn_hw_valid_rtc_data_addr(base)) { @@ -859,10 +855,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, } /* event log header */ - capacity = iwl_read_targ_mem(bus(trans), base); - mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32))); - num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32))); + capacity = iwl_read_targ_mem(trans, base); + mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); + num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); + next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " @@ -885,7 +881,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, } #ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log) + if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; #else @@ -905,7 +901,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, if (!*buf) return -ENOMEM; } - if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) { + if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { /* * if uCode has wrapped back to top of log, * start at the oldest entry, @@ -945,7 +941,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) struct isr_statistics *isr_stats = &trans_pcie->isr_stats; - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Ack/clear/reset pending uCode interrupts. * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, @@ -958,15 +954,15 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * hardware bugs here by ACKing all the possible interrupts so that * interrupt coalescing can still be achieved. */ - iwl_write32(bus(trans), CSR_INT, + iwl_write32(trans, CSR_INT, trans_pcie->inta | ~trans_pcie->inta_mask); inta = trans_pcie->inta; #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { + if (iwl_have_debug_level(IWL_DL_ISR)) { /* just for debug */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); + inta_mask = iwl_read32(trans, CSR_INT_MASK); IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", inta, inta_mask); } @@ -975,7 +971,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* saved interrupt in inta variable now we can reset trans_pcie->inta */ trans_pcie->inta = 0; - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* Now service all interrupt bits discovered above. */ if (inta & CSR_INT_BIT_HW_ERR) { @@ -993,7 +989,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) } #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { + if (iwl_have_debug_level(IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ if (inta & CSR_INT_BIT_SCD) { IWL_DEBUG_ISR(trans, "Scheduler finished to transmit " @@ -1013,30 +1009,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { - int hw_rf_kill = 0; - if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) - hw_rf_kill = 1; + bool hw_rfkill; + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); IWL_WARN(trans, "RF_KILL bit toggled to %s.\n", - hw_rf_kill ? "disable radio" : "enable radio"); + hw_rfkill ? "disable radio" : "enable radio"); isr_stats->rfkill++; - /* driver only loads ucode once setting the interface up. - * the driver allows loading the ucode even if the radio - * is killed. Hence update the killswitch state here. The - * rfkill handler will care about restarting if needed. - */ - if (!test_bit(STATUS_ALIVE, &trans->shrd->status)) { - if (hw_rf_kill) - set_bit(STATUS_RF_KILL_HW, - &trans->shrd->status); - else - clear_bit(STATUS_RF_KILL_HW, - &trans->shrd->status); - iwl_set_hw_rfkill_state(priv(trans), hw_rf_kill); - } + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); handled |= CSR_INT_BIT_RF_KILL; } @@ -1061,7 +1043,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); - for (i = 0; i < hw_params(trans).max_txq_num; i++) + for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) iwl_txq_update_write_ptr(trans, &trans_pcie->txq[i]); @@ -1078,12 +1060,12 @@ void iwl_irq_tasklet(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "Rx interrupt\n"); if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - iwl_write32(bus(trans), CSR_FH_INT_STATUS, + iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_RX_MASK); } if (inta & CSR_INT_BIT_RX_PERIODIC) { handled |= CSR_INT_BIT_RX_PERIODIC; - iwl_write32(bus(trans), + iwl_write32(trans, CSR_INT, CSR_INT_BIT_RX_PERIODIC); } /* Sending RX interrupt require many steps to be done in the @@ -1098,10 +1080,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans) */ /* Disable periodic interrupt; we use it as just a one-shot. */ - iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, + iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_DIS); +#ifdef CONFIG_IWLWIFI_IDI + iwl_amfh_rx_handler(); +#else iwl_rx_handle(trans); - +#endif /* * Enable periodic interrupt in 8 msec only if we received * real RX interrupt (instead of just periodic int), to catch @@ -1110,7 +1095,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * to extend the periodic interrupt; one-shot is enough. */ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) - iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, + iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_ENA); isr_stats->rx++; @@ -1118,13 +1103,13 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* This "Tx" DMA channel is used only for loading uCode */ if (inta & CSR_INT_BIT_FH_TX) { - iwl_write32(bus(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); + iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ - trans->ucode_write_complete = 1; - wake_up(&trans->shrd->wait_command_queue); + trans_pcie->ucode_write_complete = true; + wake_up(&trans_pcie->ucode_write_waitq); } if (inta & ~handled) { @@ -1139,11 +1124,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* Re-enable all interrupts */ /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) + if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status)) iwl_enable_interrupts(trans); /* Re-enable RF_KILL if it occurred */ else if (handled & CSR_INT_BIT_RF_KILL) - iwl_enable_rfkill_int(priv(trans)); + iwl_enable_rfkill_int(trans); } /****************************************************************************** @@ -1164,7 +1149,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); if (trans_pcie->ict_tbl) { - dma_free_coherent(bus(trans)->dev, ICT_SIZE, + dma_free_coherent(trans->dev, ICT_SIZE, trans_pcie->ict_tbl, trans_pcie->ict_tbl_dma); trans_pcie->ict_tbl = NULL; @@ -1184,7 +1169,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->ict_tbl = - dma_alloc_coherent(bus(trans)->dev, ICT_SIZE, + dma_alloc_coherent(trans->dev, ICT_SIZE, &trans_pcie->ict_tbl_dma, GFP_KERNEL); if (!trans_pcie->ict_tbl) @@ -1213,7 +1198,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) /* Device is going up inform it about using ICT interrupt table, * also we need to tell the driver to start using ICT interrupt. */ -int iwl_reset_ict(struct iwl_trans *trans) +void iwl_reset_ict(struct iwl_trans *trans) { u32 val; unsigned long flags; @@ -1221,9 +1206,9 @@ int iwl_reset_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); if (!trans_pcie->ict_tbl) - return 0; + return; - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); iwl_disable_interrupts(trans); memset(trans_pcie->ict_tbl, 0, ICT_SIZE); @@ -1235,14 +1220,12 @@ int iwl_reset_ict(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); - iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); + iwl_write32(trans, CSR_DRAM_INT_TBL_REG, val); trans_pcie->use_ict = true; trans_pcie->ict_index = 0; - iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask); + iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); iwl_enable_interrupts(trans); - spin_unlock_irqrestore(&trans->shrd->lock, flags); - - return 0; + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } /* Device is going down disable ict interrupt usage */ @@ -1253,9 +1236,9 @@ void iwl_disable_ict(struct iwl_trans *trans) unsigned long flags; - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); trans_pcie->use_ict = false; - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } static irqreturn_t iwl_isr(int irq, void *data) @@ -1270,21 +1253,21 @@ static irqreturn_t iwl_isr(int irq, void *data) if (!trans) return IRQ_NONE; - trace_iwlwifi_dev_irq(priv(trans)); + trace_iwlwifi_dev_irq(trans->dev); trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Disable (but don't clear!) interrupts here to avoid * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* Discover which interrupts are active/pending */ - inta = iwl_read32(bus(trans), CSR_INT); + inta = iwl_read32(trans, CSR_INT); /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, @@ -1302,8 +1285,8 @@ static irqreturn_t iwl_isr(int irq, void *data) } #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { - inta_fh = iwl_read32(bus(trans), CSR_FH_INT_STATUS); + if (iwl_have_debug_level(IWL_DL_ISR)) { + inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " "fh 0x%08x\n", inta, inta_mask, inta_fh); } @@ -1313,22 +1296,22 @@ static irqreturn_t iwl_isr(int irq, void *data) /* iwl_irq_tasklet() will service interrupts and re-enable them */ if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); - else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); unplugged: - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return IRQ_HANDLED; none: /* re-enable interrupts here since we don't have anything to service. */ /* only Re-enable if disabled by irq and no schedules tasklet. */ - if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return IRQ_NONE; } @@ -1360,24 +1343,24 @@ irqreturn_t iwl_isr_ict(int irq, void *data) if (!trans_pcie->use_ict) return iwl_isr(irq, data); - trace_iwlwifi_dev_irq(priv(trans)); + trace_iwlwifi_dev_irq(trans->dev); - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Disable (but don't clear!) interrupts here to avoid * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, * or due to sporadic interrupts thrown from our NIC. */ read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); - trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read); + trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); if (!read) { IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); goto none; @@ -1396,7 +1379,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); - trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, + trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, read); } while (read); @@ -1424,7 +1407,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) /* iwl_irq_tasklet() will service interrupts and re-enable them */ if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); - else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) { /* Allow interrupt if was disabled by this handler and * no tasklet was schedules, We should not enable interrupt, @@ -1433,17 +1416,17 @@ irqreturn_t iwl_isr_ict(int irq, void *data) iwl_enable_interrupts(trans); } - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return IRQ_HANDLED; none: /* re-enable interrupts here since we don't have anything to service. * only Re-enable if disabled by irq. */ - if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && + if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && !trans_pcie->inta) iwl_enable_interrupts(trans); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return IRQ_NONE; } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index bd29568177e..e92972fd6ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -35,11 +35,49 @@ #include "iwl-prph.h" #include "iwl-io.h" #include "iwl-agn-hw.h" +#include "iwl-op-mode.h" #include "iwl-trans-pcie-int.h" #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 +/* + * mac80211 queues, ACs, hardware queues, FIFOs. + * + * Cf. http://wireless.kernel.org/en/developers/Documentation/mac80211/queues + * + * Mac80211 uses the following numbers, which we get as from it + * by way of skb_get_queue_mapping(skb): + * + * VO 0 + * VI 1 + * BE 2 + * BK 3 + * + * + * Regular (not A-MPDU) frames are put into hardware queues corresponding + * to the FIFOs, see comments in iwl-prph.h. Aggregated frames get their + * own queue per aggregation session (RA/TID combination), such queues are + * set up to map into FIFOs too, for which we need an AC->FIFO mapping. In + * order to map frames to the right queue, we also need an AC->hw queue + * mapping. This is implemented here. + * + * Due to the way hw queues are set up (by the hw specific code), the AC->hw + * queue mapping is the identity mapping. + */ + +static const u8 tid_to_ac[] = { + IEEE80211_AC_BE, + IEEE80211_AC_BK, + IEEE80211_AC_BK, + IEEE80211_AC_BE, + IEEE80211_AC_VI, + IEEE80211_AC_VI, + IEEE80211_AC_VO, + IEEE80211_AC_VO +}; + + /** * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ @@ -98,9 +136,9 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) if (txq->need_update == 0) return; - if (hw_params(trans).shadow_reg_enable) { + if (cfg(trans)->base_params->shadow_reg_enable) { /* shadow register enabled */ - iwl_write32(bus(trans), HBUS_TARG_WRPTR, + iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); } else { /* if we're trying to save power */ @@ -108,18 +146,18 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) /* wake up nic if it's powered down ... * uCode will wake up, and interrupt us again, so next * time we'll skip this part. */ - reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); + reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup," " GP1 = 0x%x\n", txq_id, reg); - iwl_set_bit(bus(trans), CSR_GP_CNTRL, + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); return; } - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, + iwl_write_direct32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); /* @@ -128,7 +166,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) * trying to tx (during RFKILL, we're not trying to tx). */ } else - iwl_write32(bus(trans), HBUS_TARG_WRPTR, + iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); } txq->need_update = 0; @@ -190,14 +228,14 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, /* Unmap tx_cmd */ if (num_tbs) - dma_unmap_single(bus(trans)->dev, + dma_unmap_single(trans->dev, dma_unmap_addr(meta, mapping), dma_unmap_len(meta, len), DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) - dma_unmap_single(bus(trans)->dev, iwl_tfd_tb_get_addr(tfd, i), + dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), dma_dir); } @@ -216,6 +254,8 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, { struct iwl_tfd *tfd_tmp = txq->tfds; + lockdep_assert_held(&txq->lock); + iwlagn_unmap_tfd(trans, &txq->meta[index], &tfd_tmp[index], dma_dir); /* free SKB */ @@ -229,7 +269,7 @@ void iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, * freed and that the queue is not empty - free the skb */ if (skb) { - iwl_free_skb(priv(trans), skb); + iwl_op_mode_free_skb(trans->op_mode, skb); txq->skbs[index] = NULL; } } @@ -357,7 +397,7 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != trans->shrd->cmd_queue) + if (txq_id != trans_pcie->cmd_queue) sta_id = tx_cmd->sta_id; bc_ent = cpu_to_le16(1 | (sta_id << 12)); @@ -383,14 +423,14 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, tbl_dw_addr = trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); - tbl_dw = iwl_read_targ_mem(bus(trans), tbl_dw_addr); + tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); if (txq_id & 0x1) tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); else tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - iwl_write_targ_mem(bus(trans), tbl_dw_addr, tbl_dw); + iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); return 0; } @@ -399,7 +439,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) { /* Simply stop the queue, but don't change any configuration; * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(bus(trans), + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); @@ -409,9 +449,9 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) { IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d", txq_id, index & 0xff); - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, + iwl_write_direct32(trans, HBUS_TARG_WRPTR, (index & 0xff) | (txq_id << 8)); - iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index); + iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); } void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, @@ -423,7 +463,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, int active = test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0; - iwl_write_prph(bus(trans), SCD_QUEUE_STATUS_BITS(txq_id), + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | @@ -431,9 +471,21 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, txq->sched_retry = scd_retry; - IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n", - active ? "Activate" : "Deactivate", - scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); + if (active) + IWL_DEBUG_TX_QUEUES(trans, "Activate %s Queue %d on FIFO %d\n", + scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); + else + IWL_DEBUG_TX_QUEUES(trans, "Deactivate %s Queue %d\n", + scd_retry ? "BA" : "AC/CMD", txq_id); +} + +static inline int get_ac_from_tid(u16 tid) +{ + if (likely(tid < ARRAY_SIZE(tid_to_ac))) + return tid_to_ac[tid]; + + /* no support for TIDs 8-15 yet */ + return -EINVAL; } static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, @@ -478,7 +530,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, } txq_id = trans_pcie->agg_txq[sta_id][tid]; - if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) { + if (WARN_ON_ONCE(!is_agg_txqid_valid(trans, txq_id))) { IWL_ERR(trans, "queue number out of range: %d, must be %d to %d\n", txq_id, IWLAGN_FIRST_AMPDU_QUEUE, @@ -489,7 +541,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, ra_tid = BUILD_RAxTID(sta_id, tid); - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Stop this Tx queue before configuring it */ iwlagn_tx_queue_stop_scheduler(trans, txq_id); @@ -498,10 +550,10 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(bus(trans), SCD_QUEUECHAIN_SEL, (1<<txq_id)); + iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, (1<<txq_id)); /* enable aggregations for the queue */ - iwl_set_bits_prph(bus(trans), SCD_AGGR_SEL, (1<<txq_id)); + iwl_set_bits_prph(trans, SCD_AGGR_SEL, (1<<txq_id)); /* Place first TFD at index corresponding to start sequence number. * Assumes that ssn_idx is valid (!= 0xFFF) */ @@ -510,7 +562,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, iwl_trans_set_wr_ptrs(trans, txq_id, ssn); /* Set up Tx window size and frame limit for this queue */ - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << @@ -520,7 +572,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - iwl_set_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], @@ -529,7 +581,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, trans_pcie->txq[txq_id].sta_id = sta_id; trans_pcie->txq[txq_id].tid = tid; - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } /* @@ -543,7 +595,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int txq_id; - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) if (!test_and_set_bit(txq_id, &trans_pcie->txq_ctx_active_msk)) return txq_id; @@ -573,7 +626,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u8 txq_id = trans_pcie->agg_txq[sta_id][tid]; - if (WARN_ON_ONCE(is_agg_txqid_valid(trans, txq_id) == false)) { + if (WARN_ON_ONCE(!is_agg_txqid_valid(trans, txq_id))) { IWL_ERR(trans, "queue number out of range: %d, must be %d to %d\n", txq_id, IWLAGN_FIRST_AMPDU_QUEUE, @@ -584,7 +637,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) iwlagn_tx_queue_stop_scheduler(trans, txq_id); - iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id)); + iwl_clear_bits_prph(trans, SCD_AGGR_SEL, (1 << txq_id)); trans_pcie->agg_txq[sta_id][tid] = 0; trans_pcie->txq[txq_id].q.read_ptr = 0; @@ -592,7 +645,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) /* supposes that ssn_idx is valid (!= 0xFFF) */ iwl_trans_set_wr_ptrs(trans, txq_id, 0); - iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); iwl_txq_ctx_deactivate(trans_pcie, txq_id); iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); return 0; @@ -612,15 +665,13 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_queue *q = &txq->q; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; dma_addr_t phys_addr; - unsigned long flags; u32 idx; u16 copy_size, cmd_size; - bool is_ct_kill = false; bool had_nocopy = false; int i; u8 *cmd_dest; @@ -635,12 +686,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return -EIO; } - if ((trans->shrd->ucode_owner == IWL_OWNERSHIP_TM) && - !(cmd->flags & CMD_ON_DEMAND)) { - IWL_DEBUG_HC(trans, "tm own the uCode, no regular hcmd send\n"); - return -EIO; - } - copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); @@ -670,23 +715,13 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE)) return -EINVAL; - if (iwl_is_rfkill(trans->shrd) || iwl_is_ctkill(trans->shrd)) { - IWL_WARN(trans, "Not sending command - %s KILL\n", - iwl_is_rfkill(trans->shrd) ? "RF" : "CT"); - return -EIO; - } - - spin_lock_irqsave(&trans->hcmd_lock, flags); + spin_lock_bh(&txq->lock); if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { - spin_unlock_irqrestore(&trans->hcmd_lock, flags); + spin_unlock_bh(&txq->lock); IWL_ERR(trans, "No space in command queue\n"); - is_ct_kill = iwl_check_for_ct_kill(priv(trans)); - if (!is_ct_kill) { - IWL_ERR(trans, "Restarting adapter queue is full\n"); - iwlagn_fw_error(priv(trans), false); - } + iwl_op_mode_cmd_queue_full(trans->op_mode); return -ENOSPC; } @@ -703,7 +738,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) out_cmd->hdr.cmd = cmd->id; out_cmd->hdr.flags = 0; out_cmd->hdr.sequence = - cpu_to_le16(QUEUE_TO_SEQ(trans->shrd->cmd_queue) | + cpu_to_le16(QUEUE_TO_SEQ(trans_pcie->cmd_queue) | INDEX_TO_SEQ(q->write_ptr)); /* and copy the data that needs to be copied */ @@ -723,11 +758,11 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, - q->write_ptr, idx, trans->shrd->cmd_queue); + q->write_ptr, idx, trans_pcie->cmd_queue); - phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size, + phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { idx = -ENOMEM; goto out; } @@ -748,10 +783,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) continue; if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - phys_addr = dma_map_single(bus(trans)->dev, + phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], cmd->len[i], DMA_BIDIRECTIONAL); - if (dma_mapping_error(bus(trans)->dev, phys_addr)) { + if (dma_mapping_error(trans->dev, phys_addr)) { iwlagn_unmap_tfd(trans, out_meta, &txq->tfds[q->write_ptr], DMA_BIDIRECTIONAL); @@ -775,7 +810,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) /* check that tracing gets all possible blocks */ BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3); #ifdef CONFIG_IWLWIFI_DEVICE_TRACING - trace_iwlwifi_dev_hcmd(priv(trans), cmd->flags, + trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags, trace_bufs[0], trace_lens[0], trace_bufs[1], trace_lens[1], trace_bufs[2], trace_lens[2]); @@ -786,7 +821,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) iwl_txq_update_write_ptr(trans, txq); out: - spin_unlock_irqrestore(&trans->hcmd_lock, flags); + spin_unlock_bh(&txq->lock); return idx; } @@ -805,6 +840,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, struct iwl_queue *q = &txq->q; int nfreed = 0; + lockdep_assert_held(&txq->lock); + if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), " "index %d is out of range [0-%d] %d %d.\n", __func__, @@ -818,7 +855,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, if (nfreed++ > 0) { IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx, q->write_ptr, q->read_ptr); - iwlagn_fw_error(priv(trans), false); + iwl_op_mode_nic_error(trans->op_mode); } } @@ -834,7 +871,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, +void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, int handler_status) { struct iwl_rx_packet *pkt = rxb_addr(rxb); @@ -845,21 +882,22 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue]; - unsigned long flags; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced * in the queue management code. */ - if (WARN(txq_id != trans->shrd->cmd_queue, + if (WARN(txq_id != trans_pcie->cmd_queue, "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", - txq_id, trans->shrd->cmd_queue, sequence, - trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr, - trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) { + txq_id, trans_pcie->cmd_queue, sequence, + trans_pcie->txq[trans_pcie->cmd_queue].q.read_ptr, + trans_pcie->txq[trans_pcie->cmd_queue].q.write_ptr)) { iwl_print_hex_error(trans, pkt, 32); return; } + spin_lock(&txq->lock); + cmd_index = get_cmd_index(&txq->q, index); cmd = txq->cmd[cmd_index]; meta = &txq->meta[cmd_index]; @@ -871,13 +909,14 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { - meta->source->reply_page = (unsigned long)rxb_addr(rxb); + struct page *p = rxb_steal_page(rxb); + + meta->source->resp_pkt = pkt; + meta->source->_rx_page_addr = (unsigned long)page_address(p); + meta->source->_rx_page_order = hw_params(trans).rx_page_order; meta->source->handler_status = handler_status; - rxb->page = NULL; } - spin_lock_irqsave(&trans->hcmd_lock, flags); - iwl_hcmd_queue_reclaim(trans, txq_id, index); if (!(meta->flags & CMD_ASYNC)) { @@ -889,12 +928,12 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb, clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->hdr.cmd)); - wake_up(&trans->shrd->wait_command_queue); + wake_up(&trans->wait_command_queue); } meta->flags = 0; - spin_unlock_irqrestore(&trans->hcmd_lock, flags); + spin_unlock(&txq->lock); } #define HOST_COMPLETE_TIMEOUT (2 * HZ) @@ -908,12 +947,9 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) return -EINVAL; - if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) - return -EBUSY; - ret = iwl_enqueue_hcmd(trans, cmd); if (ret < 0) { - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; @@ -927,26 +963,22 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) int cmd_idx; int ret; - lockdep_assert_held(&trans->shrd->mutex); - IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", get_cmd_string(cmd->id)); - if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status)) - return -EBUSY; - - - if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) { - IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n", - get_cmd_string(cmd->id)); - return -ECANCELED; - } if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) { IWL_ERR(trans, "Command %s failed: FW Error\n", get_cmd_string(cmd->id)); return -EIO; } - set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); + + if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, + &trans->shrd->status))) { + IWL_ERR(trans, "Command %s: a command is already active!\n", + get_cmd_string(cmd->id)); + return -EIO; + } + IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", get_cmd_string(cmd->id)); @@ -954,27 +986,27 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) if (cmd_idx < 0) { ret = cmd_idx; clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status); - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; } - ret = wait_event_timeout(trans->shrd->wait_command_queue, + ret = wait_event_timeout(trans->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status), HOST_COMPLETE_TIMEOUT); if (!ret) { if (test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status)) { struct iwl_tx_queue *txq = - &trans_pcie->txq[trans->shrd->cmd_queue]; + &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_queue *q = &txq->q; - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Error sending %s: time out after %dms.\n", get_cmd_string(cmd->id), jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); - IWL_DEBUG_QUIET_RFKILL(trans, + IWL_ERR(trans, "Current CMD queue read_ptr %d write_ptr %d\n", q->read_ptr, q->write_ptr); @@ -986,7 +1018,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) } } - if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) { + if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { IWL_ERR(trans, "Error: Response NULL in '%s'\n", get_cmd_string(cmd->id)); ret = -EIO; @@ -1003,13 +1035,13 @@ cancel: * in later, it will possibly set an invalid * address (cmd->meta.source). */ - trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &= + trans_pcie->txq[trans_pcie->cmd_queue].meta[cmd_idx].flags &= ~CMD_WANT_SKB; } - if (cmd->reply_page) { - iwl_free_pages(trans->shrd, cmd->reply_page); - cmd->reply_page = 0; + if (cmd->resp_pkt) { + iwl_free_resp(cmd); + cmd->resp_pkt = NULL; } return ret; @@ -1034,9 +1066,11 @@ int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, int freed = 0; /* This function is not meant to release cmd queue*/ - if (WARN_ON(txq_id == trans->shrd->cmd_queue)) + if (WARN_ON(txq_id == trans_pcie->cmd_queue)) return 0; + lockdep_assert_held(&txq->lock); + /*Since we free until index _not_ inclusive, the one before index is * the last we will free. This one must be used */ last_to_free = iwl_queue_dec_wrap(index, q->n_bd); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 324d06dfb69..b4f796c82e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,8 +60,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +#include <linux/pci.h> +#include <linux/pci-aspm.h> #include <linux/interrupt.h> #include <linux/debugfs.h> +#include <linux/sched.h> #include <linux/bitops.h> #include <linux/gfp.h> @@ -73,12 +76,18 @@ #include "iwl-eeprom.h" #include "iwl-agn-hw.h" +#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) + +#define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ + (((1<<cfg(trans)->base_params->num_of_queues) - 1) &\ + (~(1<<(trans_pcie)->cmd_queue))) + static int iwl_trans_rx_alloc(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - struct device *dev = bus(trans)->dev; + struct device *dev = trans->dev; memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); @@ -122,7 +131,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) /* In the reset function, these buffers may have been allocated * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].page != NULL) { - dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma, + dma_unmap_page(trans->dev, rxq->pool[i].page_dma, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); __free_pages(rxq->pool[i].page, @@ -146,17 +155,17 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; /* Stop Rx DMA */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); /* Reset driver's Rx queue write index */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); /* Tell device where to find RBD circular buffer in DRAM */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, (u32)(rxq->bd_dma >> 8)); /* Tell device where in DRAM to update its Rx status */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, rxq->rb_stts_dma >> 4); /* Enable Rx DMA @@ -167,7 +176,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, * RB timeout 0x10 * 256 RBDs */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | @@ -177,7 +186,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); /* Set interrupt coalescing timer to default (2048 usecs) */ - iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); } static int iwl_rx_init(struct iwl_trans *trans) @@ -215,10 +224,10 @@ static int iwl_rx_init(struct iwl_trans *trans) iwl_trans_rx_hw_init(trans, rxq); - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); rxq->need_update = 1; iwl_rx_queue_update_write_ptr(trans, rxq); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return 0; } @@ -242,13 +251,13 @@ static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) iwl_trans_rxq_free_rx_bufs(trans); spin_unlock_irqrestore(&rxq->lock, flags); - dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE, + dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); rxq->bd = NULL; if (rxq->rb_stts) - dma_free_coherent(bus(trans)->dev, + dma_free_coherent(trans->dev, sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); else @@ -261,8 +270,8 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans) { /* stop Rx DMA */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG, + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); } @@ -272,7 +281,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, if (WARN_ON(ptr->addr)) return -EINVAL; - ptr->addr = dma_alloc_coherent(bus(trans)->dev, size, + ptr->addr = dma_alloc_coherent(trans->dev, size, &ptr->dma, GFP_KERNEL); if (!ptr->addr) return -ENOMEM; @@ -286,7 +295,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, if (unlikely(!ptr->addr)) return; - dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } @@ -296,6 +305,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, { size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; int i; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); if (WARN_ON(txq->meta || txq->cmd || txq->skbs || txq->tfds)) return -EINVAL; @@ -308,7 +318,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, if (!txq->meta || !txq->cmd) goto error; - if (txq_id == trans->shrd->cmd_queue) + if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) { txq->cmd[i] = kmalloc(sizeof(struct iwl_device_cmd), GFP_KERNEL); @@ -319,7 +329,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, /* Alloc driver data array and TFD circular buffer */ /* Driver private data, only for Tx (not command) queues, * not shared with device. */ - if (txq_id != trans->shrd->cmd_queue) { + if (txq_id != trans_pcie->cmd_queue) { txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->skbs[0]), GFP_KERNEL); if (!txq->skbs) { @@ -333,7 +343,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, /* Circular buffer of transmit frame descriptors (TFDs), * shared with device */ - txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz, + txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); @@ -347,7 +357,7 @@ error: txq->skbs = NULL; /* since txq->cmd has been zeroed, * all non allocated cmd[i] will be NULL */ - if (txq->cmd && txq_id == trans->shrd->cmd_queue) + if (txq->cmd && txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) kfree(txq->cmd[i]); kfree(txq->meta); @@ -385,11 +395,13 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, if (ret) return ret; + spin_lock_init(&txq->lock); + /* * Tell nic where to find circular buffer of Tx Frame Descriptors for * given Tx queue, and enable the DMA channel used for that queue. * Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id), + iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), txq->q.dma_addr >> 8); return 0; @@ -404,8 +416,6 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; enum dma_data_direction dma_dir; - unsigned long flags; - spinlock_t *lock; if (!q->n_bd) return; @@ -413,22 +423,19 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) /* In the command queue, all the TBs are mapped as BIDI * so unmap them as such. */ - if (txq_id == trans->shrd->cmd_queue) { + if (txq_id == trans_pcie->cmd_queue) dma_dir = DMA_BIDIRECTIONAL; - lock = &trans->hcmd_lock; - } else { + else dma_dir = DMA_TO_DEVICE; - lock = &trans->shrd->sta_lock; - } - spin_lock_irqsave(lock, flags); + spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { /* The read_ptr needs to bound by q->n_window */ iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr), dma_dir); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } - spin_unlock_irqrestore(lock, flags); + spin_unlock_bh(&txq->lock); } /** @@ -443,7 +450,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; - struct device *dev = bus(trans)->dev; + struct device *dev = trans->dev; int i; if (WARN_ON(!txq)) return; @@ -452,7 +459,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) /* De-alloc array of command/tx buffers */ - if (txq_id == trans->shrd->cmd_queue) + if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < txq->q.n_window; i++) kfree(txq->cmd[i]); @@ -490,7 +497,7 @@ static void iwl_trans_pcie_tx_free(struct iwl_trans *trans) /* Tx queues */ if (trans_pcie->txq) { for (txq_id = 0; - txq_id < hw_params(trans).max_txq_num; txq_id++) + txq_id < cfg(trans)->base_params->num_of_queues; txq_id++) iwl_tx_queue_free(trans, txq_id); } @@ -515,7 +522,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) int txq_id, slots_num; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 scd_bc_tbls_size = hw_params(trans).max_txq_num * + u16 scd_bc_tbls_size = cfg(trans)->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); /*It is not allowed to alloc twice, so warn when this happens. @@ -539,7 +546,7 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) goto error; } - trans_pcie->txq = kcalloc(hw_params(trans).max_txq_num, + trans_pcie->txq = kcalloc(cfg(trans)->base_params->num_of_queues, sizeof(struct iwl_tx_queue), GFP_KERNEL); if (!trans_pcie->txq) { IWL_ERR(trans, "Not enough memory for txq\n"); @@ -548,8 +555,9 @@ static int iwl_trans_tx_alloc(struct iwl_trans *trans) } /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { - slots_num = (txq_id == trans->shrd->cmd_queue) ? + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) { + slots_num = (txq_id == trans_pcie->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], slots_num, txq_id); @@ -581,20 +589,21 @@ static int iwl_tx_init(struct iwl_trans *trans) alloc = true; } - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); /* Turn off all Tx DMA fifos */ - iwl_write_prph(bus(trans), SCD_TXFACT, 0); + iwl_write_prph(trans, SCD_TXFACT, 0); /* Tell NIC where to find the "keep warm" buffer */ - iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG, + iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, trans_pcie->kw.dma >> 4); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) { - slots_num = (txq_id == trans->shrd->cmd_queue) ? + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) { + slots_num = (txq_id == trans_pcie->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], slots_num, txq_id); @@ -619,49 +628,220 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) * to set power to V_AUX, do: if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) - iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VAUX, ~APMG_PS_CTRL_MSK_PWR_SRC); */ - iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~APMG_PS_CTRL_MSK_PWR_SRC); } +/* 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 + +static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) +{ + int pos; + u16 pci_lnk_ctl; + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + + struct pci_dev *pci_dev = trans_pcie->pci_dev; + + pos = pci_pcie_cap(pci_dev); + pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; +} + +static void iwl_apm_config(struct iwl_trans *trans) +{ + /* + * 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(trans); + + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); + dev_printk(KERN_INFO, trans->dev, + "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); + dev_printk(KERN_INFO, trans->dev, + "L1 Disabled; Enabling L0S\n"); + } + trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); +} + +/* + * Start up NIC's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_apm_stop()) + * NOTE: This does not load uCode nor start the embedded processor + */ +static int iwl_apm_init(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int ret = 0; + IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); + + /* + * Use "set_bit" below rather than "write", to preserve any hardware + * bits already set by default after reset. + */ + + /* Disable L0S exit timer (platform NMI Work/Around) */ + iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); + + /* + * Disable L0s without affecting L1; + * don't wait for ICH L0s (ICH bug W/A) + */ + iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); + + /* Set FH wait threshold to maximum (HW error during stress W/A) */ + iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); + + /* + * Enable HAP INTA (interrupt from management bus) to + * wake device's PCI Express link L1a -> L0s + */ + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); + + iwl_apm_config(trans); + + /* Configure analog phase-lock-loop before activating to D0A */ + if (cfg(trans)->base_params->pll_cfg_val) + iwl_set_bit(trans, CSR_ANA_PLL_CFG, + cfg(trans)->base_params->pll_cfg_val); + + /* + * Set "initialization complete" bit to move adapter from + * D0U* --> D0A* (powered-up active) state. + */ + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + + /* + * Wait for clock stabilization; once stabilized, access to + * device-internal resources is supported, e.g. iwl_write_prph() + * and accesses to uCode SRAM. + */ + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); + if (ret < 0) { + IWL_DEBUG_INFO(trans, "Failed to init the card\n"); + goto out; + } + + /* + * Enable DMA clock and wait for it to stabilize. + * + * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits + * do not disable clocks. This preserves any hardware bits already + * set by default in "CLK_CTRL_REG" after reset. + */ + iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); + udelay(20); + + /* Disable L1-Active */ + iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); + + set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); + +out: + return ret; +} + +static int iwl_apm_stop_master(struct iwl_trans *trans) +{ + int ret = 0; + + /* stop device's busmaster DMA activity */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + + ret = iwl_poll_bit(trans, CSR_RESET, + CSR_RESET_REG_FLAG_MASTER_DISABLED, + CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); + if (ret) + IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); + + IWL_DEBUG_INFO(trans, "stop master\n"); + + return ret; +} + +static void iwl_apm_stop(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); + + clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); + + /* Stop device's DMA activity */ + iwl_apm_stop_master(trans); + + /* Reset the entire device */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + + udelay(10); + + /* + * Clear "initialization complete" bit to move adapter from + * D0A* (powered-up Active) --> D0U* (Uninitialized) state. + */ + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); +} + static int iwl_nic_init(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); unsigned long flags; /* nic_init */ - spin_lock_irqsave(&trans->shrd->lock, flags); - iwl_apm_init(priv(trans)); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + iwl_apm_init(trans); /* Set interrupt coalescing calibration timer to default (512 usecs) */ - iwl_write8(bus(trans), CSR_INT_COALESCING, + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); iwl_set_pwr_vmain(trans); - iwl_nic_config(priv(trans)); + iwl_op_mode_nic_config(trans->op_mode); +#ifndef CONFIG_IWLWIFI_IDI /* Allocate the RX queue, or reset if it is already allocated */ iwl_rx_init(trans); +#endif /* Allocate or reset and init all Tx and Command queues */ if (iwl_tx_init(trans)) return -ENOMEM; - if (hw_params(trans).shadow_reg_enable) { + if (cfg(trans)->base_params->shadow_reg_enable) { /* enable shadow regs in HW */ - iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL, + iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); } - set_bit(STATUS_INIT, &trans->shrd->status); - return 0; } @@ -672,11 +852,11 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) { int ret; - iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); /* See if we got it */ - ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); @@ -686,21 +866,22 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) } /* Note: returns standard 0/-ERROR code */ -static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans) +static int iwl_prepare_card_hw(struct iwl_trans *trans) { int ret; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); ret = iwl_set_hw_ready(trans); + /* If the card is ready, exit 0 */ if (ret >= 0) return 0; /* If HW is not ready, prepare the conditions to check again */ - iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); - ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); @@ -767,13 +948,90 @@ static const u8 iwlagn_pan_ac_to_queue[] = { 7, 6, 5, 4, }; -static int iwl_trans_pcie_start_device(struct iwl_trans *trans) +/* + * ucode + */ +static int iwl_load_section(struct iwl_trans *trans, u8 section_num, + const struct fw_desc *section) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + dma_addr_t phy_addr = section->p_addr; + u32 byte_cnt = section->len; + u32 dst_addr = section->offset; + int ret; + + trans_pcie->ucode_write_complete = false; + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); + + iwl_write_direct32(trans, + FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); + + iwl_write_direct32(trans, + FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), + phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); + + iwl_write_direct32(trans, + FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), + (iwl_get_dma_hi_addr(phy_addr) + << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | + FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | + FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); + + IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n", + section_num); + ret = wait_event_timeout(trans_pcie->ucode_write_waitq, + trans_pcie->ucode_write_complete, 5 * HZ); + if (!ret) { + IWL_ERR(trans, "Could not load the [%d] uCode section\n", + section_num); + return -ETIMEDOUT; + } + + return 0; +} + +static int iwl_load_given_ucode(struct iwl_trans *trans, + const struct fw_img *image) +{ + int ret = 0; + int i; + + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { + if (!image->sec[i].p_addr) + break; + + ret = iwl_load_section(trans, i, &image->sec[i]); + if (ret) + return ret; + } + + /* Remove all resets to allow NIC to operate */ + iwl_write32(trans, CSR_RESET, 0); + + return 0; +} + +static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, + const struct fw_img *fw) { int ret; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + bool hw_rfkill; - trans->shrd->ucode_owner = IWL_OWNERSHIP_DRIVER; trans_pcie->ac_to_queue[IWL_RXON_CTX_BSS] = iwlagn_bss_ac_to_queue; trans_pcie->ac_to_queue[IWL_RXON_CTX_PAN] = iwlagn_pan_ac_to_queue; @@ -783,26 +1041,23 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) trans_pcie->mcast_queue[IWL_RXON_CTX_BSS] = 0; trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; - if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && - iwl_trans_pcie_prepare_card_hw(trans)) { + /* This may fail if AMT took ownership of the device */ + if (iwl_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); return -EIO; } /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(bus(trans), CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - else - set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); - if (iwl_is_rfkill(trans->shrd)) { - iwl_set_hw_rfkill_state(priv(trans), true); - iwl_enable_interrupts(trans); + if (hw_rfkill) { + iwl_enable_rfkill_int(trans); return -ERFKILL; } - iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); ret = iwl_nic_init(trans); if (ret) { @@ -811,31 +1066,37 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) } /* make sure rfkill handshake bits are cleared */ - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); /* clear (again), then enable host interrupts */ - iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); iwl_enable_interrupts(trans); /* really make sure rfkill handshake bits are cleared */ - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - return 0; + /* Load the given image to the HW */ + return iwl_load_given_ucode(trans, fw); } /* * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask - * must be called under priv->shrd->lock and mac access + * must be called under the irq lock and with MAC access */ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) { - iwl_write_prph(bus(trans), SCD_TXFACT, mask); + struct iwl_trans_pcie __maybe_unused *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + + lockdep_assert_held(&trans_pcie->irq_lock); + + iwl_write_prph(trans, SCD_TXFACT, mask); } -static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) +static void iwl_tx_start(struct iwl_trans *trans) { const struct queue_to_fifo_ac *queue_to_fifo; struct iwl_trans_pcie *trans_pcie = @@ -845,49 +1106,50 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) int i, chan; u32 reg_val; - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); trans_pcie->scd_base_addr = - iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR); + iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; /* reset conext data memory */ for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); /* reset tx status memory */ for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); for (; a < trans_pcie->scd_base_addr + - SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); + SCD_TRANS_TBL_OFFSET_QUEUE( + cfg(trans)->base_params->num_of_queues); a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); - iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR, + iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) - iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan), + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); /* Update FH chicken bits */ - reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG, + reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); + iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL, - SCD_QUEUECHAIN_SEL_ALL(trans)); - iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0); + iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, + SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie)); + iwl_write_prph(trans, SCD_AGGR_SEL, 0); /* initiate the queues */ - for (i = 0; i < hw_params(trans).max_txq_num; i++) { - iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0); - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8)); - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + for (i = 0; i < cfg(trans)->base_params->num_of_queues; i++) { + iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); + iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i), 0); - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i) + sizeof(u32), ((SCD_WIN_SIZE << @@ -898,8 +1160,8 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); } - iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK, - IWL_MASK(0, hw_params(trans).max_txq_num)); + iwl_write_prph(trans, SCD_INTERRUPT_MASK, + IWL_MASK(0, cfg(trans)->base_params->num_of_queues)); /* Activate all Tx DMA/FIFO channels */ iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); @@ -910,7 +1172,7 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) else queue_to_fifo = iwlagn_default_queue_to_tx_fifo; - iwl_trans_set_wr_ptrs(trans, trans->shrd->cmd_queue, 0); + iwl_trans_set_wr_ptrs(trans, trans_pcie->cmd_queue, 0); /* make sure all queue are not stopped */ memset(&trans_pcie->queue_stopped[0], 0, @@ -941,40 +1203,47 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) fifo, 0); } - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* Enable L1-Active */ - iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG, + iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } +static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) +{ + iwl_reset_ict(trans); + iwl_tx_start(trans); +} + /** * iwlagn_txq_ctx_stop - Stop all Tx DMA channels */ static int iwl_trans_tx_stop(struct iwl_trans *trans) { - int ch, txq_id; + int ch, txq_id, ret; unsigned long flags; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); /* Turn off all Tx DMA fifos */ - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); iwl_trans_txq_set_sched(trans, 0); /* Stop each Tx DMA channel, and wait for it to be idle */ for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { - iwl_write_direct32(bus(trans), + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG, + ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), - 1000)) + 1000); + if (ret < 0) IWL_ERR(trans, "Failing on timeout while stopping" " DMA channel %d [0x%08x]", ch, - iwl_read_direct32(bus(trans), + iwl_read_direct32(trans, FH_TSSR_TX_STATUS_REG)); } - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); if (!trans_pcie->txq) { IWL_WARN(trans, "Stopping tx queues that aren't allocated..."); @@ -982,7 +1251,8 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) } /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < hw_params(trans).max_txq_num; txq_id++) + for (txq_id = 0; txq_id < cfg(trans)->base_params->num_of_queues; + txq_id++) iwl_tx_queue_unmap(trans, txq_id); return 0; @@ -994,9 +1264,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); /* tell the device to stop sending interrupts */ - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); iwl_disable_interrupts(trans); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* device going down, Stop using ICT table */ iwl_disable_ict(trans); @@ -1008,36 +1278,50 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) * restart. So don't process again if the device is * already dead. */ - if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { + if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { iwl_trans_tx_stop(trans); +#ifndef CONFIG_IWLWIFI_IDI iwl_trans_rx_stop(trans); - +#endif /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(bus(trans), APMG_CLK_DIS_REG, + iwl_write_prph(trans, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(5); } /* Make sure (redundant) we've released our request to stay awake */ - iwl_clear_bit(bus(trans), CSR_GP_CNTRL, + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - iwl_apm_stop(priv(trans)); + iwl_apm_stop(trans); /* Upon stop, the APM issues an interrupt if HW RF kill is set. * Clean again the interrupt here */ - spin_lock_irqsave(&trans->shrd->lock, flags); + spin_lock_irqsave(&trans_pcie->irq_lock, flags); iwl_disable_interrupts(trans); - spin_unlock_irqrestore(&trans->shrd->lock, flags); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* wait to make sure we flush pending tasklet*/ - synchronize_irq(bus(trans)->irq); + synchronize_irq(trans_pcie->irq); tasklet_kill(&trans_pcie->irq_tasklet); + cancel_work_sync(&trans_pcie->rx_replenish); + /* stop and reset the on-board processor */ - iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); +} + +static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) +{ + /* let the ucode operate on its own */ + iwl_write32(trans, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); + + iwl_disable_interrupts(trans); + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, @@ -1092,6 +1376,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq = &trans_pcie->txq[txq_id]; q = &txq->q; + spin_lock(&txq->lock); + /* In AGG mode, the index in the ring must correspond to the WiFi * sequence number. This is a HW requirements to help the SCD to parse * the BA. @@ -1134,11 +1420,11 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ - txcmd_phys = dma_map_single(bus(trans)->dev, + txcmd_phys = dma_map_single(trans->dev, &dev_cmd->hdr, firstlen, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys))) - return -1; + if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) + goto out_err; dma_unmap_addr_set(out_meta, mapping, txcmd_phys); dma_unmap_len_set(out_meta, len, firstlen); @@ -1153,14 +1439,14 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, * if any (802.11 null frames have no payload). */ secondlen = skb->len - hdr_len; if (secondlen > 0) { - phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len, + phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { - dma_unmap_single(bus(trans)->dev, + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { + dma_unmap_single(trans->dev, dma_unmap_addr(out_meta, mapping), dma_unmap_len(out_meta, len), DMA_BIDIRECTIONAL); - return -1; + goto out_err; } } @@ -1174,7 +1460,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, offsetof(struct iwl_tx_cmd, scratch); /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen, + dma_sync_single_for_cpu(trans->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); @@ -1182,16 +1468,14 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", le16_to_cpu(dev_cmd->hdr.sequence)); IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); - iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); - iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); /* Set up entry for this TFD in Tx byte-count array */ iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); - dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, + dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, DMA_BIDIRECTIONAL); - trace_iwlwifi_dev_tx(priv(trans), + trace_iwlwifi_dev_tx(trans->dev, &((struct iwl_tfd *)txq->tfds)[txq->q.write_ptr], sizeof(struct iwl_tfd), &dev_cmd->hdr, firstlen, @@ -1212,46 +1496,77 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq->need_update = 1; iwl_txq_update_write_ptr(trans, txq); } else { - iwl_stop_queue(trans, txq, "Queue is full"); + iwl_stop_queue(trans, txq); } } + spin_unlock(&txq->lock); return 0; + out_err: + spin_unlock(&txq->lock); + return -1; } -static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) -{ - /* Remove all resets to allow NIC to operate */ - iwl_write32(bus(trans), CSR_RESET, 0); -} - -static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) +static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int err; + bool hw_rfkill; trans_pcie->inta_mask = CSR_INI_SET_MASK; - tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)trans); + if (!trans_pcie->irq_requested) { + tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)trans); - iwl_alloc_isr_ict(trans); + iwl_alloc_isr_ict(trans); - err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED, - DRV_NAME, trans); + err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, + DRV_NAME, trans); + if (err) { + IWL_ERR(trans, "Error allocating IRQ %d\n", + trans_pcie->irq); + goto error; + } + + INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); + trans_pcie->irq_requested = true; + } + + err = iwl_prepare_card_hw(trans); if (err) { - IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq); - iwl_free_isr_ict(trans); - return err; + IWL_ERR(trans, "Error while preparing HW: %d", err); + goto err_free_irq; } - INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); - return 0; + iwl_apm_init(trans); + + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); + + return err; + +err_free_irq: + free_irq(trans_pcie->irq, trans); +error: + iwl_free_isr_ict(trans); + tasklet_kill(&trans_pcie->irq_tasklet); + return err; +} + +static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) +{ + iwl_apm_stop(trans); + + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); + + /* Even if we stop the HW, we still want the RF kill interrupt */ + iwl_enable_rfkill_int(trans); } static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, - int txq_id, int ssn, u32 status, - struct sk_buff_head *skbs) + int txq_id, int ssn, struct sk_buff_head *skbs) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; @@ -1259,6 +1574,8 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, int tfd_num = ssn & (txq->q.n_bd - 1); int freed = 0; + spin_lock(&txq->lock); + txq->time_stamp = jiffies; if (unlikely(txq_id >= IWLAGN_FIRST_AMPDU_QUEUE && @@ -1273,6 +1590,7 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, IWL_DEBUG_TX_QUEUES(trans, "Bad queue mapping txq_id %d, " "agg_txq[sta_id[tid] %d", txq_id, trans_pcie->agg_txq[sta_id][tid]); + spin_unlock(&txq->lock); return 1; } @@ -1281,115 +1599,90 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, txq_id, iwl_get_queue_ac(txq), txq->q.read_ptr, tfd_num, ssn); freed = iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); - if (iwl_queue_space(&txq->q) > txq->q.low_mark && - (!txq->sched_retry || - status != TX_STATUS_FAIL_PASSIVE_NO_RX)) - iwl_wake_queue(trans, txq, "Packets reclaimed"); + if (iwl_queue_space(&txq->q) > txq->q.low_mark) + iwl_wake_queue(trans, txq); } + + spin_unlock(&txq->lock); return 0; } -static void iwl_trans_pcie_free(struct iwl_trans *trans) +static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) { - iwl_calib_free_results(trans); - iwl_trans_pcie_tx_free(trans); - iwl_trans_pcie_rx_free(trans); - free_irq(bus(trans)->irq, trans); - iwl_free_isr_ict(trans); - trans->shrd->trans = NULL; - kfree(trans); + writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } -#ifdef CONFIG_PM_SLEEP -static int iwl_trans_pcie_suspend(struct iwl_trans *trans) +static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) { - /* - * This function is called when system goes into suspend state - * mac80211 will call iwlagn_mac_stop() from the mac80211 suspend - * function first but since iwlagn_mac_stop() has no knowledge of - * who the caller is, - * it will not call apm_ops.stop() to stop the DMA operation. - * Calling apm_ops.stop here to make sure we stop the DMA. - * - * But of course ... if we have configured WoWLAN then we did other - * things already :-) - */ - if (!trans->shrd->wowlan) { - iwl_apm_stop(priv(trans)); - } else { - iwl_disable_interrupts(trans); - iwl_clear_bit(bus(trans), CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - } - - return 0; + writel(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); } -static int iwl_trans_pcie_resume(struct iwl_trans *trans) +static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) { - bool hw_rfkill = false; - - iwl_enable_interrupts(trans); + return readl(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); +} - if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) - hw_rfkill = true; +static void iwl_trans_pcie_configure(struct iwl_trans *trans, + const struct iwl_trans_config *trans_cfg) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - if (hw_rfkill) - set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + trans_pcie->cmd_queue = trans_cfg->cmd_queue; + if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) + trans_pcie->n_no_reclaim_cmds = 0; else - clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); - - iwl_set_hw_rfkill_state(priv(trans), hw_rfkill); - - return 0; + trans_pcie->n_no_reclaim_cmds = trans_cfg->n_no_reclaim_cmds; + if (trans_pcie->n_no_reclaim_cmds) + memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, + trans_pcie->n_no_reclaim_cmds * sizeof(u8)); } -#endif /* CONFIG_PM_SLEEP */ -static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, - enum iwl_rxon_context_id ctx, - const char *msg) +static void iwl_trans_pcie_free(struct iwl_trans *trans) { - u8 ac, txq_id; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - for (ac = 0; ac < AC_NUM; ac++) { - txq_id = trans_pcie->ac_to_queue[ctx][ac]; - IWL_DEBUG_TX_QUEUES(trans, "Queue Status: Q[%d] %s\n", - ac, - (atomic_read(&trans_pcie->queue_stop_count[ac]) > 0) - ? "stopped" : "awake"); - iwl_wake_queue(trans, &trans_pcie->txq[txq_id], msg); + iwl_trans_pcie_tx_free(trans); +#ifndef CONFIG_IWLWIFI_IDI + iwl_trans_pcie_rx_free(trans); +#endif + if (trans_pcie->irq_requested == true) { + free_irq(trans_pcie->irq, trans); + iwl_free_isr_ict(trans); } -} -const struct iwl_trans_ops trans_ops_pcie; + pci_disable_msi(trans_pcie->pci_dev); + iounmap(trans_pcie->hw_base); + pci_release_regions(trans_pcie->pci_dev); + pci_disable_device(trans_pcie->pci_dev); -static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) -{ - struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + - sizeof(struct iwl_trans_pcie), - GFP_KERNEL); - if (iwl_trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(iwl_trans); - iwl_trans->ops = &trans_ops_pcie; - iwl_trans->shrd = shrd; - trans_pcie->trans = iwl_trans; - spin_lock_init(&iwl_trans->hcmd_lock); - } + trans->shrd->trans = NULL; + kfree(trans); +} - return iwl_trans; +#ifdef CONFIG_PM_SLEEP +static int iwl_trans_pcie_suspend(struct iwl_trans *trans) +{ + return 0; } -static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, - const char *msg) +static int iwl_trans_pcie_resume(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + bool hw_rfkill; + + hw_rfkill = !(iwl_read32(trans, CSR_GP_CNTRL) & + CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW); + + if (hw_rfkill) + iwl_enable_rfkill_int(trans); + else + iwl_enable_interrupts(trans); - iwl_stop_queue(trans, &trans_pcie->txq[txq_id], msg); + iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); + + return 0; } +#endif /* CONFIG_PM_SLEEP */ #define IWL_FLUSH_WAIT_MS 2000 @@ -1403,8 +1696,8 @@ static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) int ret = 0; /* waiting for all the tx frames complete might take a while */ - for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { - if (cnt == trans->shrd->cmd_queue) + for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { + if (cnt == trans_pcie->cmd_queue) continue; txq = &trans_pcie->txq[cnt]; q = &txq->q; @@ -1446,9 +1739,9 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", q->read_ptr, q->write_ptr); IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", - iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt)) + iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt)) & (TFD_QUEUE_SIZE_MAX - 1), - iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt))); + iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); return 1; } @@ -1502,7 +1795,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) pos += scnprintf(*buf + pos, bufsz - pos, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); + iwl_read_direct32(trans, fh_tbl[i])); } return pos; } @@ -1511,7 +1804,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { IWL_ERR(trans, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); + iwl_read_direct32(trans, fh_tbl[i])); } return 0; } @@ -1581,7 +1874,7 @@ void iwl_dump_csr(struct iwl_trans *trans) for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { IWL_ERR(trans, " %25s: 0X%08x\n", get_csr_string(csr_tbl[i]), - iwl_read32(bus(trans), csr_tbl[i])); + iwl_read32(trans, csr_tbl[i])); } } @@ -1649,7 +1942,9 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, int pos = 0; int cnt; int ret; - const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num; + size_t bufsz; + + bufsz = sizeof(char) * 64 * cfg(trans)->base_params->num_of_queues; if (!trans_pcie->txq) { IWL_ERR(trans, "txq not ready\n"); @@ -1659,7 +1954,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, if (!buf) return -ENOMEM; - for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) { + for (cnt = 0; cnt < cfg(trans)->base_params->num_of_queues; cnt++) { txq = &trans_pcie->txq[cnt]; q = &txq->q; pos += scnprintf(buf + pos, bufsz - pos, @@ -1902,14 +2197,13 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, #endif /*CONFIG_IWLWIFI_DEBUGFS */ const struct iwl_trans_ops trans_ops_pcie = { - .alloc = iwl_trans_pcie_alloc, - .request_irq = iwl_trans_pcie_request_irq, - .start_device = iwl_trans_pcie_start_device, - .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, + .start_hw = iwl_trans_pcie_start_hw, + .stop_hw = iwl_trans_pcie_stop_hw, + .fw_alive = iwl_trans_pcie_fw_alive, + .start_fw = iwl_trans_pcie_start_fw, .stop_device = iwl_trans_pcie_stop_device, - .tx_start = iwl_trans_pcie_tx_start, - .wake_any_queue = iwl_trans_pcie_wake_any_queue, + .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, .send_cmd = iwl_trans_pcie_send_cmd, @@ -1920,10 +2214,7 @@ const struct iwl_trans_ops trans_ops_pcie = { .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc, .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, - .kick_nic = iwl_trans_pcie_kick_nic, - .free = iwl_trans_pcie_free, - .stop_queue = iwl_trans_pcie_stop_queue, .dbgfs_register = iwl_trans_pcie_dbgfs_register, @@ -1934,4 +2225,121 @@ const struct iwl_trans_ops trans_ops_pcie = { .suspend = iwl_trans_pcie_suspend, .resume = iwl_trans_pcie_resume, #endif + .write8 = iwl_trans_pcie_write8, + .write32 = iwl_trans_pcie_write32, + .read32 = iwl_trans_pcie_read32, + .configure = iwl_trans_pcie_configure, }; + +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct iwl_trans_pcie *trans_pcie; + struct iwl_trans *trans; + u16 pci_cmd; + int err; + + trans = kzalloc(sizeof(struct iwl_trans) + + sizeof(struct iwl_trans_pcie), GFP_KERNEL); + + if (WARN_ON(!trans)) + return NULL; + + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + trans->ops = &trans_ops_pcie; + trans->shrd = shrd; + trans_pcie->trans = trans; + spin_lock_init(&trans_pcie->irq_lock); + init_waitqueue_head(&trans_pcie->ucode_write_waitq); + + /* 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) { + dev_printk(KERN_ERR, &pdev->dev, + "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + } + + err = pci_request_regions(pdev, DRV_NAME); + if (err) { + dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed"); + goto out_pci_disable_device; + } + + trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); + if (!trans_pcie->hw_base) { + dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed"); + err = -ENODEV; + goto out_pci_release_regions; + } + + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_base = %p\n", trans_pcie->hw_base); + + dev_printk(KERN_INFO, &pdev->dev, + "HW Revision ID = 0x%X\n", pdev->revision); + + /* 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) + dev_printk(KERN_ERR, &pdev->dev, + "pci_enable_msi failed(0X%x)", err); + + trans->dev = &pdev->dev; + trans_pcie->irq = pdev->irq; + trans_pcie->pci_dev = pdev; + trans->hw_rev = iwl_read32(trans, CSR_HW_REV); + trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; + snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), + "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); + + /* 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); + } + + /* Initialize the wait queue for commands */ + init_waitqueue_head(&trans->wait_command_queue); + + return trans; + +out_pci_release_regions: + pci_release_regions(pdev); +out_pci_disable_device: + pci_disable_device(pdev); +out_no_pci: + kfree(trans); + return NULL; +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index e6bf3f55477..0c81cbaa808 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,23 +63,132 @@ #ifndef __iwl_trans_h__ #define __iwl_trans_h__ -#include <linux/debugfs.h> -#include <linux/skbuff.h> +#include <linux/ieee80211.h> +#include <linux/mm.h> /* for page_address */ #include "iwl-shared.h" -#include "iwl-commands.h" +#include "iwl-debug.h" - /*This file includes the declaration that are exported from the transport - * layer */ +/** + * DOC: Transport layer - what is it ? + * + * The tranport layer is the layer that deals with the HW directly. It provides + * an abstraction of the underlying HW to the upper layer. The transport layer + * doesn't provide any policy, algorithm or anything of this kind, but only + * mechanisms to make the HW do something.It is not completely stateless but + * close to it. + * We will have an implementation for each different supported bus. + */ + +/** + * DOC: Life cycle of the transport layer + * + * The transport layer has a very precise life cycle. + * + * 1) A helper function is called during the module initialization and + * registers the bus driver's ops with the transport's alloc function. + * 2) Bus's probe calls to the transport layer's allocation functions. + * Of course this function is bus specific. + * 3) This allocation functions will spawn the upper layer which will + * register mac80211. + * + * 4) At some point (i.e. mac80211's start call), the op_mode will call + * the following sequence: + * start_hw + * start_fw + * + * 5) Then when finished (or reset): + * stop_fw (a.k.a. stop device for the moment) + * stop_hw + * + * 6) Eventually, the free function will be called. + */ struct iwl_priv; struct iwl_shared; +struct iwl_op_mode; +struct fw_img; +struct sk_buff; +struct dentry; +/** + * DOC: Host command section + * + * A host command is a commaned issued by the upper layer to the fw. There are + * several versions of fw that have several APIs. The transport layer is + * completely agnostic to these differences. + * The transport does provide helper functionnality (i.e. SYNC / ASYNC mode), + */ #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) +#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f) +#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) +#define SEQ_TO_INDEX(s) ((s) & 0xff) +#define INDEX_TO_SEQ(i) ((i) & 0xff) +#define SEQ_RX_FRAME cpu_to_le16(0x8000) + +/** + * struct iwl_cmd_header + * + * This header format appears in the beginning of each command sent from the + * driver, and each response/notification received from uCode. + */ +struct iwl_cmd_header { + u8 cmd; /* Command ID: REPLY_RXON, etc. */ + u8 flags; /* 0:5 reserved, 6 abort, 7 internal */ + /* + * The driver sets up the sequence number to values of its choosing. + * uCode does not use this value, but passes it back to the driver + * when sending the response to each driver-originated command, so + * the driver can match the response to the command. Since the values + * don't get used by uCode, the driver may set up an arbitrary format. + * + * There is one exception: uCode sets bit 15 when it originates + * the response/notification, i.e. when the response/notification + * is not a direct response to a command sent by the driver. For + * example, uCode issues REPLY_RX when it sends a received frame + * to the driver; it is not a direct response to any driver command. + * + * The Linux driver uses the following format: + * + * 0:7 tfd index - position within TX queue + * 8:12 TX queue id + * 13:14 reserved + * 15 unsolicited RX or uCode-originated notification + */ + __le16 sequence; +} __packed; + -enum { +#define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF /* bits 0-13 */ + +struct iwl_rx_packet { + /* + * The first 4 bytes of the RX frame header contain both the RX frame + * size and some flags. + * Bit fields: + * 31: flag flush RB request + * 30: flag ignore TC (terminal counter) request + * 29: flag fast IRQ request + * 28-14: Reserved + * 13-00: RX frame size + */ + __le32 len_n_flags; + struct iwl_cmd_header hdr; + u8 data[]; +} __packed; + +/** + * enum CMD_MODE - how to send the host commands ? + * + * @CMD_SYNC: The caller will be stalled until the fw responds to the command + * @CMD_ASYNC: Return right away and don't want for the response + * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the + * response. + * @CMD_ON_DEMAND: This command is sent by the test mode pipe. + */ +enum CMD_MODE { CMD_SYNC = 0, CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), @@ -104,25 +213,38 @@ struct iwl_device_cmd { #define IWL_MAX_CMD_TFDS 2 +/** + * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command + * + * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's + * ring. The transport layer doesn't map the command's buffer to DMA, but + * rather copies it to an previously allocated DMA buffer. This flag tells + * the transport layer not to copy the command, but to map the existing + * buffer. This can save memcpy and is worth with very big comamnds. + */ enum iwl_hcmd_dataflag { IWL_HCMD_DFL_NOCOPY = BIT(0), }; /** * struct iwl_host_cmd - Host command to the uCode + * * @data: array of chunks that composes the data of the host command - * @reply_page: pointer to the page that holds the response to the host command + * @resp_pkt: response packet, if %CMD_WANT_SKB was set + * @_rx_page_order: (internally used to free response packet) + * @_rx_page_addr: (internally used to free response packet) * @handler_status: return value of the handler of the command * (put in setup_rx_handlers) - valid for SYNC mode only - * @callback: - * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC + * @flags: can be CMD_* * @len: array of the lenths of the chunks in data - * @dataflags: + * @dataflags: IWL_HCMD_DFL_* * @id: id of the host command */ struct iwl_host_cmd { const void *data[IWL_MAX_CMD_TFDS]; - unsigned long reply_page; + struct iwl_rx_packet *resp_pkt; + unsigned long _rx_page_addr; + u32 _rx_page_order; int handler_status; u32 flags; @@ -131,48 +253,109 @@ struct iwl_host_cmd { u8 id; }; +static inline void iwl_free_resp(struct iwl_host_cmd *cmd) +{ + free_pages(cmd->_rx_page_addr, cmd->_rx_page_order); +} + +struct iwl_rx_cmd_buffer { + struct page *_page; +}; + +static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r) +{ + return page_address(r->_page); +} + +static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) +{ + struct page *p = r->_page; + r->_page = NULL; + return p; +} + +#define MAX_NO_RECLAIM_CMDS 6 + +/** + * struct iwl_trans_config - transport configuration + * + * @op_mode: pointer to the upper layer. + * Must be set before any other call. + * @cmd_queue: the index of the command queue. + * Must be set before start_fw. + * @no_reclaim_cmds: Some devices erroneously don't set the + * SEQ_RX_FRAME bit on some notifications, this is the + * list of such notifications to filter. Max length is + * %MAX_NO_RECLAIM_CMDS. + * @n_no_reclaim_cmds: # of commands in list + */ +struct iwl_trans_config { + struct iwl_op_mode *op_mode; + u8 cmd_queue; + const u8 *no_reclaim_cmds; + int n_no_reclaim_cmds; +}; + /** * struct iwl_trans_ops - transport specific operations - * @alloc: allocates the meta data (not the queues themselves) - * @request_irq: requests IRQ - will be called before the FW load in probe flow - * @start_device: allocates and inits all the resources for the transport - * layer. - * @prepare_card_hw: claim the ownership on the HW. Will be called during - * probe. - * @tx_start: starts and configures all the Tx fifo - usually done once the fw - * is alive. - * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* + * + * All the handlers MUST be implemented + * + * @start_hw: starts the HW- from that point on, the HW can send interrupts + * May sleep + * @stop_hw: stops the HW- from that point on, the HW will be in low power but + * will still issue interrupt if the HW RF kill is triggered. + * May sleep + * @start_fw: allocates and inits all the resources for the transport + * layer. Also kick a fw image. + * May sleep + * @fw_alive: called when the fw sends alive notification + * May sleep * @stop_device:stops the whole device (embedded CPU put to reset) + * May sleep + * @wowlan_suspend: put the device into the correct mode for WoWLAN during + * suspend. This is optional, if not implemented WoWLAN will not be + * supported. This callback may sleep. * @send_cmd:send a host command + * May sleep only if CMD_SYNC is set * @tx: send an skb + * Must be atomic * @reclaim: free packet until ssn. Returns a list of freed packets. + * Must be atomic * @tx_agg_alloc: allocate resources for a TX BA session + * Must be atomic * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is - * ready and a successful ADDBA response has been received. + * ready and a successful ADDBA response has been received. + * May sleep * @tx_agg_disable: de-configure a Tx queue to send AMPDUs - * @kick_nic: remove the RESET from the embedded CPU and let it run + * Must be atomic * @free: release all the ressource for the transport layer itself such as - * irq, tasklet etc... - * @stop_queue: stop a specific queue + * irq, tasklet etc... From this point on, the device may not issue + * any interrupt (incl. RFKILL). + * May sleep * @check_stuck_queue: check if a specific queue is stuck * @wait_tx_queue_empty: wait until all tx queues are empty + * May sleep * @dbgfs_register: add the dbgfs files under this directory. Files will be * automatically deleted. * @suspend: stop the device unless WoWLAN is configured * @resume: resume activity of the device + * @write8: write a u8 to a register at offset ofs from the BAR + * @write32: write a u32 to a register at offset ofs from the BAR + * @read32: read a u32 register at offset ofs from the BAR + * @configure: configure parameters required by the transport layer from + * the op_mode. May be called several times before start_fw, can't be + * called after that. */ struct iwl_trans_ops { - struct iwl_trans *(*alloc)(struct iwl_shared *shrd); - int (*request_irq)(struct iwl_trans *iwl_trans); - int (*start_device)(struct iwl_trans *trans); - int (*prepare_card_hw)(struct iwl_trans *trans); + int (*start_hw)(struct iwl_trans *iwl_trans); + void (*stop_hw)(struct iwl_trans *iwl_trans); + int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); + void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); - void (*tx_start)(struct iwl_trans *trans); - void (*wake_any_queue)(struct iwl_trans *trans, - enum iwl_rxon_context_id ctx, - const char *msg); + void (*wowlan_suspend)(struct iwl_trans *trans); int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); @@ -180,8 +363,7 @@ struct iwl_trans_ops { struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid); int (*reclaim)(struct iwl_trans *trans, int sta_id, int tid, - int txq_id, int ssn, u32 status, - struct sk_buff_head *skbs); + int txq_id, int ssn, struct sk_buff_head *skbs); int (*tx_agg_disable)(struct iwl_trans *trans, int sta_id, int tid); @@ -191,12 +373,8 @@ struct iwl_trans_ops { enum iwl_rxon_context_id ctx, int sta_id, int tid, int frame_limit, u16 ssn); - void (*kick_nic)(struct iwl_trans *trans); - void (*free)(struct iwl_trans *trans); - void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); - int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); int (*check_stuck_queue)(struct iwl_trans *trans, int q); int (*wait_tx_queue_empty)(struct iwl_trans *trans); @@ -204,127 +382,165 @@ struct iwl_trans_ops { int (*suspend)(struct iwl_trans *trans); int (*resume)(struct iwl_trans *trans); #endif + void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); + void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); + u32 (*read32)(struct iwl_trans *trans, u32 ofs); + void (*configure)(struct iwl_trans *trans, + const struct iwl_trans_config *trans_cfg); }; -/* one for each uCode image (inst/data, boot/init/runtime) */ -struct fw_desc { - dma_addr_t p_addr; /* hardware address */ - void *v_addr; /* software address */ - u32 len; /* size in bytes */ -}; - -struct fw_img { - struct fw_desc code; /* firmware code image */ - struct fw_desc data; /* firmware data image */ -}; - -/* Opaque calibration results */ -struct iwl_calib_result { - struct list_head list; - size_t cmd_len; - struct iwl_calib_hdr hdr; - /* data follows */ +/** + * enum iwl_trans_state - state of the transport layer + * + * @IWL_TRANS_NO_FW: no fw has sent an alive response + * @IWL_TRANS_FW_ALIVE: a fw has sent an alive response + */ +enum iwl_trans_state { + IWL_TRANS_NO_FW = 0, + IWL_TRANS_FW_ALIVE = 1, }; /** * struct iwl_trans - transport common data + * * @ops - pointer to iwl_trans_ops + * @op_mode - pointer to the op_mode * @shrd - pointer to iwl_shared which holds shared data from the upper layer - * @hcmd_lock: protects HCMD - * @ucode_write_complete: indicates that the ucode has been copied. - * @ucode_rt: run time ucode image - * @ucode_init: init ucode image - * @ucode_wowlan: wake on wireless ucode image (optional) + * @reg_lock - protect hw register access + * @dev - pointer to struct device * that represents the device + * @hw_id: a u32 with the ID of the device / subdevice. + * Set during transport allocation. + * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @nvm_device_type: indicates OTP or eeprom - * @calib_results: list head for init calibration results + * @pm_support: set to true in start_hw if link pm is supported + * @wait_command_queue: the wait_queue for SYNC host commands */ struct iwl_trans { const struct iwl_trans_ops *ops; + struct iwl_op_mode *op_mode; struct iwl_shared *shrd; - spinlock_t hcmd_lock; + enum iwl_trans_state state; + spinlock_t reg_lock; - u8 ucode_write_complete; /* the image write is complete */ - struct fw_img ucode_rt; - struct fw_img ucode_init; - struct fw_img ucode_wowlan; + struct device *dev; + u32 hw_rev; + u32 hw_id; + char hw_id_str[52]; - /* eeprom related variables */ int nvm_device_type; + bool pm_support; - /* init calibration results */ - struct list_head calib_results; + wait_queue_head_t wait_command_queue; /* pointer to trans specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ - char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); + char trans_specific[0] __aligned(sizeof(void *)); }; -static inline int iwl_trans_request_irq(struct iwl_trans *trans) +static inline void iwl_trans_configure(struct iwl_trans *trans, + const struct iwl_trans_config *trans_cfg) { - return trans->ops->request_irq(trans); + /* + * only set the op_mode for the moment. Later on, this function will do + * more + */ + trans->op_mode = trans_cfg->op_mode; + + trans->ops->configure(trans, trans_cfg); } -static inline int iwl_trans_start_device(struct iwl_trans *trans) +static inline int iwl_trans_start_hw(struct iwl_trans *trans) { - return trans->ops->start_device(trans); + might_sleep(); + + return trans->ops->start_hw(trans); } -static inline int iwl_trans_prepare_card_hw(struct iwl_trans *trans) +static inline void iwl_trans_stop_hw(struct iwl_trans *trans) { - return trans->ops->prepare_card_hw(trans); + might_sleep(); + + trans->ops->stop_hw(trans); + + trans->state = IWL_TRANS_NO_FW; } -static inline void iwl_trans_stop_device(struct iwl_trans *trans) +static inline void iwl_trans_fw_alive(struct iwl_trans *trans) { - trans->ops->stop_device(trans); + might_sleep(); + + trans->ops->fw_alive(trans); + + trans->state = IWL_TRANS_FW_ALIVE; } -static inline void iwl_trans_tx_start(struct iwl_trans *trans) +static inline int iwl_trans_start_fw(struct iwl_trans *trans, + const struct fw_img *fw) { - trans->ops->tx_start(trans); + might_sleep(); + + return trans->ops->start_fw(trans, fw); } -static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, - enum iwl_rxon_context_id ctx, - const char *msg) +static inline void iwl_trans_stop_device(struct iwl_trans *trans) { - trans->ops->wake_any_queue(trans, ctx, msg); + might_sleep(); + + trans->ops->stop_device(trans); + + trans->state = IWL_TRANS_NO_FW; } +static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans) +{ + might_sleep(); + trans->ops->wowlan_suspend(trans); +} static inline int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + return trans->ops->send_cmd(trans, cmd); } -int iwl_trans_send_cmd_pdu(struct iwl_trans *trans, u8 id, - u32 flags, u16 len, const void *data); - static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, enum iwl_rxon_context_id ctx, u8 sta_id, u8 tid) { + if (trans->state != IWL_TRANS_FW_ALIVE) + IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + return trans->ops->tx(trans, skb, dev_cmd, ctx, sta_id, tid); } static inline int iwl_trans_reclaim(struct iwl_trans *trans, int sta_id, - int tid, int txq_id, int ssn, u32 status, + int tid, int txq_id, int ssn, struct sk_buff_head *skbs) { - return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, - status, skbs); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + + return trans->ops->reclaim(trans, sta_id, tid, txq_id, ssn, skbs); } static inline int iwl_trans_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) { + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + return trans->ops->tx_agg_disable(trans, sta_id, tid); } static inline int iwl_trans_tx_agg_alloc(struct iwl_trans *trans, int sta_id, int tid) { + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + return trans->ops->tx_agg_alloc(trans, sta_id, tid); } @@ -334,12 +550,12 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, int sta_id, int tid, int frame_limit, u16 ssn) { - trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); -} + might_sleep(); -static inline void iwl_trans_kick_nic(struct iwl_trans *trans) -{ - trans->ops->kick_nic(trans); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + + trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); } static inline void iwl_trans_free(struct iwl_trans *trans) @@ -347,19 +563,19 @@ static inline void iwl_trans_free(struct iwl_trans *trans) trans->ops->free(trans); } -static inline void iwl_trans_stop_queue(struct iwl_trans *trans, int q, - const char *msg) -{ - trans->ops->stop_queue(trans, q, msg); -} - static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + return trans->ops->wait_tx_queue_empty(trans); } static inline int iwl_trans_check_stuck_queue(struct iwl_trans *trans, int q) { + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); + return trans->ops->check_stuck_queue(trans, q); } static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, @@ -380,18 +596,35 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) } #endif -/***************************************************** -* Transport layers implementations -******************************************************/ -extern const struct iwl_trans_ops trans_ops_pcie; +static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val) +{ + trans->ops->write8(trans, ofs, val); +} -int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, - const void *data, size_t len); -void iwl_dealloc_ucode(struct iwl_trans *trans); +static inline void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val) +{ + trans->ops->write32(trans, ofs, val); +} -int iwl_send_calib_results(struct iwl_trans *trans); -int iwl_calib_set(struct iwl_trans *trans, - const struct iwl_calib_hdr *cmd, int len); -void iwl_calib_free_results(struct iwl_trans *trans); +static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) +{ + return trans->ops->read32(trans, ofs); +} +/***************************************************** +* Transport layers implementations + their allocation function +******************************************************/ +struct pci_dev; +struct pci_device_id; +extern const struct iwl_trans_ops trans_ops_pcie; +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent); +int __must_check iwl_pci_register_driver(void); +void iwl_pci_unregister_driver(void); + +extern const struct iwl_trans_ops trans_ops_idi; +struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd, + void *pdev_void, + const void *ent_void); #endif /* __iwl_trans_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 36a1b5b2585..25282872883 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 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 @@ -28,12 +28,8 @@ *****************************************************************************/ #include <linux/kernel.h> -#include <linux/module.h> #include <linux/init.h> -#include <linux/sched.h> -#include <linux/dma-mapping.h> -#include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" @@ -42,6 +38,7 @@ #include "iwl-agn-calib.h" #include "iwl-trans.h" #include "iwl-fh.h" +#include "iwl-op-mode.h" static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, @@ -80,157 +77,35 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) +static inline const struct fw_img * +iwl_get_ucode_image(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { - if (desc->v_addr) - dma_free_coherent(bus->dev, desc->len, - desc->v_addr, desc->p_addr); - desc->v_addr = NULL; - desc->len = 0; -} - -static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img) -{ - iwl_free_fw_desc(bus, &img->code); - iwl_free_fw_desc(bus, &img->data); -} - -void iwl_dealloc_ucode(struct iwl_trans *trans) -{ - iwl_free_fw_img(bus(trans), &trans->ucode_rt); - iwl_free_fw_img(bus(trans), &trans->ucode_init); - iwl_free_fw_img(bus(trans), &trans->ucode_wowlan); -} - -int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, - const void *data, size_t len) -{ - if (!len) { - desc->v_addr = NULL; - return -EINVAL; - } - - desc->v_addr = dma_alloc_coherent(bus->dev, len, - &desc->p_addr, GFP_KERNEL); - if (!desc->v_addr) - return -ENOMEM; + if (ucode_type >= IWL_UCODE_TYPE_MAX) + return NULL; - desc->len = len; - memcpy(desc->v_addr, data, len); - return 0; -} - -/* - * ucode - */ -static int iwl_load_section(struct iwl_trans *trans, const char *name, - struct fw_desc *image, u32 dst_addr) -{ - struct iwl_bus *bus = bus(trans); - dma_addr_t phy_addr = image->p_addr; - u32 byte_cnt = image->len; - int ret; - - trans->ucode_write_complete = 0; - - iwl_write_direct32(bus, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); - - iwl_write_direct32(bus, - FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); - - iwl_write_direct32(bus, - FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), - phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); - - iwl_write_direct32(bus, - FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), - (iwl_get_dma_hi_addr(phy_addr) - << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); - - iwl_write_direct32(bus, - FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | - FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); - - iwl_write_direct32(bus, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | - FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - - IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name); - ret = wait_event_timeout(trans->shrd->wait_command_queue, - trans->ucode_write_complete, 5 * HZ); - if (!ret) { - IWL_ERR(trans, "Could not load the %s uCode section\n", - name); - return -ETIMEDOUT; - } - - return 0; -} - -static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, - enum iwl_ucode_type ucode_type) -{ - switch (ucode_type) { - case IWL_UCODE_INIT: - return &trans->ucode_init; - case IWL_UCODE_WOWLAN: - return &trans->ucode_wowlan; - case IWL_UCODE_REGULAR: - return &trans->ucode_rt; - case IWL_UCODE_NONE: - break; - } - return NULL; -} - -static int iwl_load_given_ucode(struct iwl_trans *trans, - enum iwl_ucode_type ucode_type) -{ - int ret = 0; - struct fw_img *image = iwl_get_ucode_image(trans, ucode_type); - - - if (!image) { - IWL_ERR(trans, "Invalid ucode requested (%d)\n", - ucode_type); - return -EINVAL; - } - - ret = iwl_load_section(trans, "INST", &image->code, - IWLAGN_RTC_INST_LOWER_BOUND); - if (ret) - return ret; - - return iwl_load_section(trans, "DATA", &image->data, - IWLAGN_RTC_DATA_LOWER_BOUND); + return &priv->fw->img[ucode_type]; } /* * Calibration */ -static int iwl_set_Xtal_calib(struct iwl_trans *trans) +static int iwl_set_Xtal_calib(struct iwl_priv *priv) { struct iwl_calib_xtal_freq_cmd cmd; __le16 *xtal_calib = - (__le16 *)iwl_eeprom_query_addr(trans->shrd, EEPROM_XTAL); + (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL); 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(trans, (void *)&cmd, sizeof(cmd)); + return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); } -static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) +static int iwl_set_temperature_offset_calib(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_cmd cmd; __le16 *offset_calib = - (__le16 *)iwl_eeprom_query_addr(trans->shrd, + (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_RAW_TEMPERATURE); memset(&cmd, 0, sizeof(cmd)); @@ -239,48 +114,48 @@ static int iwl_set_temperature_offset_calib(struct iwl_trans *trans) if (!(cmd.radio_sensor_offset)) cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; - IWL_DEBUG_CALIB(trans, "Radio sensor offset: %d\n", + IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", le16_to_cpu(cmd.radio_sensor_offset)); - return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); + return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); } -static int iwl_set_temperature_offset_calib_v2(struct iwl_trans *trans) +static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv) { struct iwl_calib_temperature_offset_v2_cmd cmd; - __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(trans->shrd, + __le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_KELVIN_TEMPERATURE); __le16 *offset_calib_low = - (__le16 *)iwl_eeprom_query_addr(trans->shrd, + (__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_RAW_TEMPERATURE); struct iwl_eeprom_calib_hdr *hdr; memset(&cmd, 0, sizeof(cmd)); iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD); - hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(trans->shrd, + hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd, EEPROM_CALIB_ALL); memcpy(&cmd.radio_sensor_offset_high, offset_calib_high, sizeof(*offset_calib_high)); memcpy(&cmd.radio_sensor_offset_low, offset_calib_low, sizeof(*offset_calib_low)); if (!(cmd.radio_sensor_offset_low)) { - IWL_DEBUG_CALIB(trans, "no info in EEPROM, use default\n"); + IWL_DEBUG_CALIB(priv, "no info in EEPROM, use default\n"); cmd.radio_sensor_offset_low = DEFAULT_RADIO_SENSOR_OFFSET; cmd.radio_sensor_offset_high = DEFAULT_RADIO_SENSOR_OFFSET; } memcpy(&cmd.burntVoltageRef, &hdr->voltage, sizeof(hdr->voltage)); - IWL_DEBUG_CALIB(trans, "Radio sensor offset high: %d\n", + IWL_DEBUG_CALIB(priv, "Radio sensor offset high: %d\n", le16_to_cpu(cmd.radio_sensor_offset_high)); - IWL_DEBUG_CALIB(trans, "Radio sensor offset low: %d\n", + IWL_DEBUG_CALIB(priv, "Radio sensor offset low: %d\n", le16_to_cpu(cmd.radio_sensor_offset_low)); - IWL_DEBUG_CALIB(trans, "Voltage Ref: %d\n", + IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n", le16_to_cpu(cmd.burntVoltageRef)); - return iwl_calib_set(trans, (void *)&cmd, sizeof(cmd)); + return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd)); } -static int iwl_send_calib_cfg(struct iwl_trans *trans) +static int iwl_send_calib_cfg(struct iwl_priv *priv) { struct iwl_calib_cfg_cmd calib_cfg_cmd; struct iwl_host_cmd cmd = { @@ -296,47 +171,47 @@ static int iwl_send_calib_cfg(struct iwl_trans *trans) calib_cfg_cmd.ucd_calib_cfg.flags = IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK; - return iwl_trans_send_cmd(trans, &cmd); + return iwl_dvm_send_cmd(priv, &cmd); } int iwlagn_rx_calib_result(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, + struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; + struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->data; int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; /* reduce the size of the length field itself */ len -= 4; - if (iwl_calib_set(trans(priv), hdr, len)) + if (iwl_calib_set(priv, hdr, len)) IWL_ERR(priv, "Failed to record calibration data %d\n", hdr->op_code); return 0; } -int iwl_init_alive_start(struct iwl_trans *trans) +int iwl_init_alive_start(struct iwl_priv *priv) { int ret; - if (cfg(trans)->bt_params && - cfg(trans)->bt_params->advanced_bt_coexist) { + if (cfg(priv)->bt_params && + cfg(priv)->bt_params->advanced_bt_coexist) { /* * Tell uCode we are ready to perform calibration * need to perform this before any calibration * no need to close the envlope since we are going * to load the runtime uCode later. */ - ret = iwl_send_bt_env(trans, IWL_BT_COEX_ENV_OPEN, + ret = iwl_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; } - ret = iwl_send_calib_cfg(trans); + ret = iwl_send_calib_cfg(priv); if (ret) return ret; @@ -344,21 +219,21 @@ int iwl_init_alive_start(struct iwl_trans *trans) * temperature offset calibration is only needed for runtime ucode, * so prepare the value now. */ - if (cfg(trans)->need_temp_offset_calib) { - if (cfg(trans)->temp_offset_v2) - return iwl_set_temperature_offset_calib_v2(trans); + if (cfg(priv)->need_temp_offset_calib) { + if (cfg(priv)->temp_offset_v2) + return iwl_set_temperature_offset_calib_v2(priv); else - return iwl_set_temperature_offset_calib(trans); + return iwl_set_temperature_offset_calib(priv); } return 0; } -static int iwl_send_wimax_coex(struct iwl_trans *trans) +static int iwl_send_wimax_coex(struct iwl_priv *priv) { struct iwl_wimax_coex_cmd coex_cmd; - if (cfg(trans)->base_params->support_wimax_coexist) { + if (cfg(priv)->base_params->support_wimax_coexist) { /* UnMask wake up src at associated sleep */ coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; @@ -377,7 +252,7 @@ static int iwl_send_wimax_coex(struct iwl_trans *trans) /* coexistence is disabled */ memset(&coex_cmd, 0, sizeof(coex_cmd)); } - return iwl_trans_send_cmd_pdu(trans, + return iwl_dvm_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD, CMD_SYNC, sizeof(coex_cmd), &coex_cmd); } @@ -404,64 +279,54 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { 0, 0, 0, 0, 0, 0, 0 }; -void iwl_send_prio_tbl(struct iwl_trans *trans) +void iwl_send_prio_tbl(struct iwl_priv *priv) { struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; memcpy(prio_tbl_cmd.prio_tbl, iwl_bt_prio_tbl, sizeof(iwl_bt_prio_tbl)); - if (iwl_trans_send_cmd_pdu(trans, + if (iwl_dvm_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE, CMD_SYNC, sizeof(prio_tbl_cmd), &prio_tbl_cmd)) - IWL_ERR(trans, "failed to send BT prio tbl command\n"); + IWL_ERR(priv, "failed to send BT prio tbl command\n"); } -int iwl_send_bt_env(struct iwl_trans *trans, u8 action, u8 type) +int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) { struct iwl_bt_coex_prot_env_cmd env_cmd; int ret; env_cmd.action = action; env_cmd.type = type; - ret = iwl_trans_send_cmd_pdu(trans, + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, CMD_SYNC, sizeof(env_cmd), &env_cmd); if (ret) - IWL_ERR(trans, "failed to send BT env command\n"); + IWL_ERR(priv, "failed to send BT env command\n"); return ret; } -static int iwl_alive_notify(struct iwl_trans *trans) +static int iwl_alive_notify(struct iwl_priv *priv) { - struct iwl_priv *priv = priv(trans); - struct iwl_rxon_context *ctx; int ret; - if (!priv->tx_cmd_pool) - priv->tx_cmd_pool = - kmem_cache_create("iwl_dev_cmd", - sizeof(struct iwl_device_cmd), - sizeof(void *), 0, NULL); + iwl_trans_fw_alive(trans(priv)); - if (!priv->tx_cmd_pool) - return -ENOMEM; + priv->passive_no_rx = false; + priv->transport_queue_stop = 0; - iwl_trans_tx_start(trans); - for_each_context(priv, ctx) - ctx->last_tx_rejected = false; - - ret = iwl_send_wimax_coex(trans); + ret = iwl_send_wimax_coex(priv); if (ret) return ret; if (!cfg(priv)->no_xtal_calib) { - ret = iwl_set_Xtal_calib(trans); + ret = iwl_set_Xtal_calib(priv); if (ret) return ret; } - return iwl_send_calib_results(trans); + return iwl_send_calib_results(priv); } @@ -470,23 +335,23 @@ static int iwl_alive_notify(struct iwl_trans *trans) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_bus *bus, - struct fw_desc *fw_desc) +static int iwl_verify_sec_sparse(struct iwl_priv *priv, + const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; u32 val; u32 i; - IWL_DEBUG_FW(bus, "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 */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, - i + IWLAGN_RTC_INST_LOWER_BOUND); - val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, + i + fw_desc->offset); + val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; } @@ -494,8 +359,8 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, return 0; } -static void iwl_print_mismatch_inst(struct iwl_bus *bus, - struct fw_desc *fw_desc) +static void iwl_print_mismatch_sec(struct iwl_priv *priv, + const struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; u32 len = fw_desc->len; @@ -503,18 +368,18 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus, u32 offs; int errors = 0; - IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(priv, "ucode inst image size is %u\n", len); - iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, - IWLAGN_RTC_INST_LOWER_BOUND); + iwl_write_direct32(trans(priv), HBUS_TARG_MEM_RADDR, + fw_desc->offset); for (offs = 0; offs < len && errors < 20; offs += sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ - val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { - IWL_ERR(bus, "uCode INST section at " + IWL_ERR(priv, "uCode INST section at " "offset 0x%x, is 0x%x, s/b 0x%x\n", offs, val, le32_to_cpu(*image)); errors++; @@ -526,24 +391,24 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus, * iwl_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ -static int iwl_verify_ucode(struct iwl_trans *trans, +static int iwl_verify_ucode(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { - struct fw_img *img = iwl_get_ucode_image(trans, ucode_type); + const struct fw_img *img = iwl_get_ucode_image(priv, ucode_type); if (!img) { - IWL_ERR(trans, "Invalid ucode requested (%d)\n", ucode_type); + IWL_ERR(priv, "Invalid ucode requested (%d)\n", ucode_type); return -EINVAL; } - if (!iwl_verify_inst_sparse(bus(trans), &img->code)) { - IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); + if (!iwl_verify_sec_sparse(priv, &img->sec[IWL_UCODE_SECTION_INST])) { + IWL_DEBUG_FW(priv, "uCode is good in inst SRAM\n"); return 0; } - IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); + IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(bus(trans), &img->code); + iwl_print_mismatch_sec(priv, &img->sec[IWL_UCODE_SECTION_INST]); return -EIO; } @@ -552,137 +417,76 @@ struct iwl_alive_data { u8 subtype; }; -static void iwl_alive_fn(struct iwl_trans *trans, +static void iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt, void *data) { + struct iwl_priv *priv = + container_of(notif_wait, struct iwl_priv, notif_wait); struct iwl_alive_data *alive_data = data; struct iwl_alive_resp *palive; - palive = &pkt->u.alive_frame; + palive = (void *)pkt->data; - IWL_DEBUG_FW(trans, "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); - trans->shrd->device_pointers.error_event_table = + priv->shrd->device_pointers.error_event_table = le32_to_cpu(palive->error_event_table_ptr); - trans->shrd->device_pointers.log_event_table = + priv->shrd->device_pointers.log_event_table = le32_to_cpu(palive->log_event_table_ptr); alive_data->subtype = palive->ver_subtype; alive_data->valid = palive->is_valid == UCODE_VALID_OK; } -/* notification wait support */ -void iwl_init_notification_wait(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - u8 cmd, - void (*fn)(struct iwl_trans *trans, - struct iwl_rx_packet *pkt, - void *data), - void *fn_data) -{ - wait_entry->fn = fn; - wait_entry->fn_data = fn_data; - wait_entry->cmd = cmd; - wait_entry->triggered = false; - wait_entry->aborted = false; - - spin_lock_bh(&shrd->notif_wait_lock); - list_add(&wait_entry->list, &shrd->notif_waits); - spin_unlock_bh(&shrd->notif_wait_lock); -} - -int iwl_wait_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry, - unsigned long timeout) -{ - int ret; - - ret = wait_event_timeout(shrd->notif_waitq, - wait_entry->triggered || wait_entry->aborted, - timeout); - - spin_lock_bh(&shrd->notif_wait_lock); - list_del(&wait_entry->list); - spin_unlock_bh(&shrd->notif_wait_lock); - - if (wait_entry->aborted) - return -EIO; - - /* return value is always >= 0 */ - if (ret <= 0) - return -ETIMEDOUT; - return 0; -} - -void iwl_remove_notification(struct iwl_shared *shrd, - struct iwl_notification_wait *wait_entry) -{ - spin_lock_bh(&shrd->notif_wait_lock); - list_del(&wait_entry->list); - spin_unlock_bh(&shrd->notif_wait_lock); -} - -void iwl_abort_notification_waits(struct iwl_shared *shrd) -{ - unsigned long flags; - struct iwl_notification_wait *wait_entry; - - spin_lock_irqsave(&shrd->notif_wait_lock, flags); - list_for_each_entry(wait_entry, &shrd->notif_waits, list) - wait_entry->aborted = true; - spin_unlock_irqrestore(&shrd->notif_wait_lock, flags); - - wake_up_all(&shrd->notif_waitq); -} - #define UCODE_ALIVE_TIMEOUT HZ #define UCODE_CALIB_TIMEOUT (2*HZ) -int iwl_load_ucode_wait_alive(struct iwl_trans *trans, +int iwl_load_ucode_wait_alive(struct iwl_priv *priv, enum iwl_ucode_type ucode_type) { struct iwl_notification_wait alive_wait; struct iwl_alive_data alive_data; + const struct fw_img *fw; int ret; enum iwl_ucode_type old_type; - ret = iwl_trans_start_device(trans); - if (ret) - return ret; + old_type = priv->shrd->ucode_type; + priv->shrd->ucode_type = ucode_type; + fw = iwl_get_ucode_image(priv, ucode_type); - iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, - iwl_alive_fn, &alive_data); + priv->ucode_loaded = false; + + if (!fw) + return -EINVAL; - old_type = trans->shrd->ucode_type; - trans->shrd->ucode_type = ucode_type; + iwl_init_notification_wait(&priv->notif_wait, &alive_wait, REPLY_ALIVE, + iwl_alive_fn, &alive_data); - ret = iwl_load_given_ucode(trans, ucode_type); + ret = iwl_trans_start_fw(trans(priv), fw); if (ret) { - trans->shrd->ucode_type = old_type; - iwl_remove_notification(trans->shrd, &alive_wait); + priv->shrd->ucode_type = old_type; + iwl_remove_notification(&priv->notif_wait, &alive_wait); return ret; } - iwl_trans_kick_nic(trans); - /* * Some things may run in the background now, but we * just wait for the ALIVE notification here. */ - ret = iwl_wait_notification(trans->shrd, &alive_wait, + ret = iwl_wait_notification(&priv->notif_wait, &alive_wait, UCODE_ALIVE_TIMEOUT); if (ret) { - trans->shrd->ucode_type = old_type; + priv->shrd->ucode_type = old_type; return ret; } if (!alive_data.valid) { - IWL_ERR(trans, "Loaded ucode is not valid!\n"); - trans->shrd->ucode_type = old_type; + IWL_ERR(priv, "Loaded ucode is not valid!\n"); + priv->shrd->ucode_type = old_type; return -EIO; } @@ -692,9 +496,9 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, * skip it for WoWLAN. */ if (ucode_type != IWL_UCODE_WOWLAN) { - ret = iwl_verify_ucode(trans, ucode_type); + ret = iwl_verify_ucode(priv, ucode_type); if (ret) { - trans->shrd->ucode_type = old_type; + priv->shrd->ucode_type = old_type; return ret; } @@ -702,41 +506,43 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, msleep(5); } - ret = iwl_alive_notify(trans); + ret = iwl_alive_notify(priv); if (ret) { - IWL_WARN(trans, + IWL_WARN(priv, "Could not complete ALIVE transition: %d\n", ret); - trans->shrd->ucode_type = old_type; + priv->shrd->ucode_type = old_type; return ret; } + priv->ucode_loaded = true; + return 0; } -int iwl_run_init_ucode(struct iwl_trans *trans) +int iwl_run_init_ucode(struct iwl_priv *priv) { struct iwl_notification_wait calib_wait; int ret; - lockdep_assert_held(&trans->shrd->mutex); + lockdep_assert_held(&priv->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!trans->ucode_init.code.len) + if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) return 0; - if (trans->shrd->ucode_type != IWL_UCODE_NONE) + if (priv->init_ucode_run) return 0; - iwl_init_notification_wait(trans->shrd, &calib_wait, + iwl_init_notification_wait(&priv->notif_wait, &calib_wait, CALIBRATION_COMPLETE_NOTIFICATION, NULL, NULL); /* Will also start the device */ - ret = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT); + ret = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); if (ret) goto error; - ret = iwl_init_alive_start(trans); + ret = iwl_init_alive_start(priv); if (ret) goto error; @@ -744,15 +550,19 @@ int iwl_run_init_ucode(struct iwl_trans *trans) * Some things may run in the background now, but we * just wait for the calibration complete notification. */ - ret = iwl_wait_notification(trans->shrd, &calib_wait, + ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, UCODE_CALIB_TIMEOUT); + if (!ret) + priv->init_ucode_run = true; goto out; error: - iwl_remove_notification(trans->shrd, &calib_wait); + iwl_remove_notification(&priv->notif_wait, &calib_wait); out: /* Whatever happened, stop the device */ - iwl_trans_stop_device(trans); + iwl_trans_stop_device(trans(priv)); + priv->ucode_loaded = false; + return ret; } diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h index abb4805fa8d..f5f7070b7e2 100644 --- a/drivers/net/wireless/iwmc3200wifi/trace.h +++ b/drivers/net/wireless/iwmc3200wifi/trace.h @@ -144,7 +144,7 @@ TRACE_EVENT(iwm_tx_packets, TP_printk( IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, " - "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes", + "ra_tid 0x%x, credit_group 0x%x, embedded_packets %d, %d bytes", IWM_PR_ARG, !__entry->eot ? "concatenated " : "", __entry->eot, __entry->seq, __entry->color, __entry->ra_tid, __entry->credit_group, __entry->npkt, __entry->bytes diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index a7cd311cb1b..3fa1ecebadf 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -1631,42 +1631,6 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, /* - * "Site survey", here just current channel and noise level - */ - -static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, - int idx, struct survey_info *survey) -{ - struct lbs_private *priv = wiphy_priv(wiphy); - s8 signal, noise; - int ret; - - if (dev == priv->mesh_dev) - return -EOPNOTSUPP; - - if (idx != 0) - ret = -ENOENT; - - lbs_deb_enter(LBS_DEB_CFG80211); - - survey->channel = ieee80211_get_channel(wiphy, - ieee80211_channel_to_frequency(priv->channel, - IEEE80211_BAND_2GHZ)); - - ret = lbs_get_rssi(priv, &signal, &noise); - if (ret == 0) { - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = noise; - } - - lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); - return ret; -} - - - - -/* * Change interface */ @@ -2068,7 +2032,6 @@ static struct cfg80211_ops lbs_cfg80211_ops = { .del_key = lbs_cfg_del_key, .set_default_key = lbs_cfg_set_default_key, .get_station = lbs_cfg_get_station, - .dump_survey = lbs_get_survey, .change_virtual_intf = lbs_change_intf, .join_ibss = lbs_join_ibss, .leave_ibss = lbs_leave_ibss, diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 3f7bf4d912b..234ee88dec9 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -815,10 +815,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev) lbs_deb_enter(LBS_DEB_CS); card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); - if (!card) { - pr_err("error in kzalloc\n"); + if (!card) goto out; - } + card->p_dev = p_dev; p_dev->priv = card; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index b5fbbc7947d..74da5f1ea24 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -261,10 +261,8 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index aff8b5743af..7ced130f4f9 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -153,10 +153,8 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data.\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 4b9e730d2c8..b7ce6a6e355 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -27,6 +27,7 @@ #include <linux/etherdevice.h> #include <linux/debugfs.h> #include <linux/module.h> +#include <linux/ktime.h> #include <net/genetlink.h> #include "mac80211_hwsim.h" @@ -321,11 +322,15 @@ struct mac80211_hwsim_data { struct dentry *debugfs_group; int power_level; + + /* difference between this hw's clock and the real clock, in usecs */ + u64 tsf_offset; }; struct hwsim_radiotap_hdr { struct ieee80211_radiotap_header hdr; + __le64 rt_tsft; u8 rt_flags; u8 rt_rate; __le16 rt_channel; @@ -367,6 +372,28 @@ static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } +static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data) +{ + struct timeval tv = ktime_to_timeval(ktime_get_real()); + u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + return cpu_to_le64(now + data->tsf_offset); +} + +static u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mac80211_hwsim_data *data = hw->priv; + return le64_to_cpu(__mac80211_hwsim_get_tsf(data)); +} + +static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u64 tsf) +{ + struct mac80211_hwsim_data *data = hw->priv; + struct timeval tv = ktime_to_timeval(ktime_get_real()); + u64 now = tv.tv_sec * USEC_PER_SEC + tv.tv_usec; + data->tsf_offset = tsf - now; +} static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, struct sk_buff *tx_skb) @@ -391,7 +418,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | + (1 << IEEE80211_RADIOTAP_TSFT) | (1 << IEEE80211_RADIOTAP_CHANNEL)); + hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); hdr->rt_flags = 0; hdr->rt_rate = txrate->bitrate / 5; hdr->rt_channel = cpu_to_le16(data->channel->center_freq); @@ -592,7 +621,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, return; nla_put_failure: - printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); } static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, @@ -610,7 +639,7 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, } memset(&rx_status, 0, sizeof(rx_status)); - /* TODO: set mactime */ + rx_status.flag |= RX_FLAG_MACTIME_MPDU; rx_status.freq = data->channel->center_freq; rx_status.band = data->channel->band; rx_status.rate_idx = info->control.rates[0].idx; @@ -654,6 +683,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, if (mac80211_hwsim_addr_match(data2, hdr->addr1)) ack = true; + rx_status.mactime = + le64_to_cpu(__mac80211_hwsim_get_tsf(data2)); memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(data2->hw, nskb); } @@ -667,6 +698,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) bool ack; struct ieee80211_tx_info *txi; u32 _pid; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; + struct mac80211_hwsim_data *data = hw->priv; + + if (ieee80211_is_beacon(mgmt->frame_control) || + ieee80211_is_probe_resp(mgmt->frame_control)) + mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); mac80211_hwsim_monitor_rx(hw, skb); @@ -763,9 +800,11 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, struct ieee80211_vif *vif) { struct ieee80211_hw *hw = arg; + struct mac80211_hwsim_data *data = hw->priv; struct sk_buff *skb; struct ieee80211_tx_info *info; u32 _pid; + struct ieee80211_mgmt *mgmt; hwsim_check_magic(vif); @@ -779,6 +818,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, return; info = IEEE80211_SKB_CB(skb); + mgmt = (struct ieee80211_mgmt *) skb->data; + mgmt->u.beacon.timestamp = __mac80211_hwsim_get_tsf(data); + mac80211_hwsim_monitor_rx(hw, skb); /* wmediumd mode check */ @@ -1199,6 +1241,8 @@ static struct ieee80211_ops mac80211_hwsim_ops = .sw_scan_start = mac80211_hwsim_sw_scan, .sw_scan_complete = mac80211_hwsim_sw_scan_complete, .flush = mac80211_hwsim_flush, + .get_tsf = mac80211_hwsim_get_tsf, + .set_tsf = mac80211_hwsim_set_tsf, }; @@ -1564,7 +1608,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, return 0; err: - printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); goto out; out: dev_kfree_skb(skb); @@ -1580,11 +1624,11 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2, wmediumd_pid = info->snd_pid; printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, " - "switching to wmediumd mode with pid %d\n", info->snd_pid); + "switching to wmediumd mode with pid %d\n", info->snd_pid); return 0; out: - printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); return -EINVAL; } @@ -1647,7 +1691,7 @@ static int hwsim_init_netlink(void) return 0; failure: - printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); + printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); return -EINVAL; } diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c index 34bba523429..a5e182b5e94 100644 --- a/drivers/net/wireless/mwifiex/11n.c +++ b/drivers/net/wireless/mwifiex/11n.c @@ -44,16 +44,16 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, ht_cap->ht_cap.ampdu_params_info = (sband->ht_cap.ampdu_factor & - IEEE80211_HT_AMPDU_PARM_FACTOR)| + IEEE80211_HT_AMPDU_PARM_FACTOR) | ((sband->ht_cap.ampdu_density << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) & IEEE80211_HT_AMPDU_PARM_DENSITY); memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs, - sizeof(sband->ht_cap.mcs)); + sizeof(sband->ht_cap.mcs)); if (priv->bss_mode == NL80211_IFTYPE_STATION || - (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask); @@ -69,8 +69,8 @@ mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type, * table which matches the requested BA status. */ static struct mwifiex_tx_ba_stream_tbl * -mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv, - enum mwifiex_ba_status ba_status) +mwifiex_get_ba_status(struct mwifiex_private *priv, + enum mwifiex_ba_status ba_status) { struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; unsigned long flags; @@ -107,12 +107,11 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, tid = del_ba_param_set >> DELBA_TID_POS; if (del_ba->del_result == BA_RESULT_SUCCESS) { - mwifiex_11n_delete_ba_stream_tbl(priv, tid, - del_ba->peer_mac_addr, TYPE_DELBA_SENT, - INITIATOR_BIT(del_ba_param_set)); + mwifiex_del_ba_tbl(priv, tid, del_ba->peer_mac_addr, + TYPE_DELBA_SENT, + INITIATOR_BIT(del_ba_param_set)); - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, - BA_STREAM_SETUP_INPROGRESS); + tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); if (tx_ba_tbl) mwifiex_send_addba(priv, tx_ba_tbl->tid, tx_ba_tbl->ra); @@ -120,18 +119,17 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv, * In case of failure, recreate the deleted stream in case * we initiated the ADDBA */ - if (INITIATOR_BIT(del_ba_param_set)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - del_ba->peer_mac_addr, tid, - BA_STREAM_SETUP_INPROGRESS); - - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv, - BA_STREAM_SETUP_INPROGRESS); - if (tx_ba_tbl) - mwifiex_11n_delete_ba_stream_tbl(priv, - tx_ba_tbl->tid, tx_ba_tbl->ra, - TYPE_DELBA_SENT, true); - } + if (!INITIATOR_BIT(del_ba_param_set)) + return 0; + + mwifiex_create_ba_tbl(priv, del_ba->peer_mac_addr, tid, + BA_SETUP_INPROGRESS); + + tx_ba_tbl = mwifiex_get_ba_status(priv, BA_SETUP_INPROGRESS); + + if (tx_ba_tbl) + mwifiex_del_ba_tbl(priv, tx_ba_tbl->tid, tx_ba_tbl->ra, + TYPE_DELBA_SENT, true); } return 0; @@ -160,18 +158,17 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv, & IEEE80211_ADDBA_PARAM_TID_MASK) >> BLOCKACKPARAM_TID_POS; if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) { - tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, + tx_ba_tbl = mwifiex_get_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr); if (tx_ba_tbl) { dev_dbg(priv->adapter->dev, "info: BA stream complete\n"); - tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE; + tx_ba_tbl->ba_status = BA_SETUP_COMPLETE; } else { dev_err(priv->adapter->dev, "BA stream not created\n"); } } else { - mwifiex_11n_delete_ba_stream_tbl(priv, tid, - add_ba_rsp->peer_mac_addr, - TYPE_DELBA_SENT, true); + mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, + TYPE_DELBA_SENT, true); if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) priv->aggr_prio_tbl[tid].ampdu_ap = BA_STREAM_NOT_ALLOWED; @@ -392,9 +389,9 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv, chan_list->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) - && (bss_desc->bcn_ht_info->ht_param & - IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) + if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 && + bss_desc->bcn_ht_info->ht_param & + IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) SET_SECONDARYCHAN(chan_list->chan_scan_param[0]. radio_type, (bss_desc->bcn_ht_info->ht_param & @@ -467,7 +464,7 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu); dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n", - max_amsdu, priv->adapter->max_tx_buf_size); + max_amsdu, priv->adapter->max_tx_buf_size); if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K) curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; @@ -507,7 +504,7 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl) { if (!tx_ba_tsr_tbl && - mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) + mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl)) return; dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl); @@ -544,16 +541,15 @@ void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv) * table which matches the given RA/TID pair. */ struct mwifiex_tx_ba_stream_tbl * -mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, - int tid, u8 *ra) +mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra) { struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl; unsigned long flags; spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { - if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN)) - && (tx_ba_tsr_tbl->tid == tid)) { + if (!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN) && + tx_ba_tsr_tbl->tid == tid) { spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); return tx_ba_tsr_tbl; @@ -567,14 +563,13 @@ mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv, * This function creates an entry in Tx BA stream table for the * given RA/TID pair. */ -void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, - u8 *ra, int tid, - enum mwifiex_ba_status ba_status) +void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, + enum mwifiex_ba_status ba_status) { struct mwifiex_tx_ba_stream_tbl *new_node; unsigned long flags; - if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) { + if (!mwifiex_get_ba_tbl(priv, tid, ra)) { new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), GFP_ATOMIC); if (!new_node) { @@ -668,9 +663,8 @@ void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba) tid = del_ba_param_set >> DELBA_TID_POS; - mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr, - TYPE_DELBA_RECEIVE, - INITIATOR_BIT(del_ba_param_set)); + mwifiex_del_ba_tbl(priv, tid, cmd_del_ba->peer_mac_addr, + TYPE_DELBA_RECEIVE, INITIATOR_BIT(del_ba_param_set)); } /* @@ -724,7 +718,7 @@ int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv, list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) { rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid; dev_dbg(priv->adapter->dev, "data: %s tid=%d\n", - __func__, rx_reo_tbl->tid); + __func__, rx_reo_tbl->tid); memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN); rx_reo_tbl++; count++; diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h index 90b421e343d..77646d777dc 100644 --- a/drivers/net/wireless/mwifiex/11n.h +++ b/drivers/net/wireless/mwifiex/11n.h @@ -46,13 +46,12 @@ void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv, struct mwifiex_tx_ba_stream_tbl *tx_tbl); void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv); -struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct +struct mwifiex_tx_ba_stream_tbl *mwifiex_get_ba_tbl(struct mwifiex_private *priv, int tid, u8 *ra); -void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra, - int tid, - enum mwifiex_ba_status ba_status); +void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, + enum mwifiex_ba_status ba_status); int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac); int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, int initiator); @@ -87,9 +86,8 @@ mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid) static inline u8 mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid) { - return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) - && ((priv->is_data_rate_auto) - || !((priv->bitmap_rates[2]) & 0x03))) + return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED) && + (priv->is_data_rate_auto || !(priv->bitmap_rates[2] & 0x03))) ? true : false); } @@ -150,11 +148,11 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid, */ static inline int mwifiex_is_ba_stream_setup(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ptr, int tid) + struct mwifiex_ra_list_tbl *ptr, int tid) { struct mwifiex_tx_ba_stream_tbl *tx_tbl; - tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra); + tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra); if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl)) return true; diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 079e5532e68..9eefb2a0ce9 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -84,7 +84,7 @@ mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr, /* Add payload */ skb_put(skb_aggr, skb_src->len); memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data, - skb_src->len); + skb_src->len); *pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len + LLC_SNAP_LEN)) & 3)) : 0; skb_put(skb_aggr, *pad); @@ -119,14 +119,14 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - - sizeof(*local_tx_pd)); + sizeof(*local_tx_pd)); if (local_tx_pd->tx_control == 0) /* TxCtrl set by user or default */ local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl); - if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (priv->adapter->pps_uapsd_mode)) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + priv->adapter->pps_uapsd_mode) { if (true == mwifiex_check_last_packet_indication(priv)) { priv->adapter->tx_lock_flag = true; local_tx_pd->flags = @@ -182,7 +182,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); - tx_info_aggr->bss_index = tx_info_src->bss_index; + tx_info_aggr->bss_type = tx_info_src->bss_type; + tx_info_aggr->bss_num = tx_info_src->bss_num; skb_aggr->priority = skb_src->priority; do { @@ -256,9 +257,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, mwifiex_write_data_complete(adapter, skb_aggr, -1); return -1; } - if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (adapter->pps_uapsd_mode) && - (adapter->tx_lock_flag)) { + if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && + adapter->pps_uapsd_mode && adapter->tx_lock_flag) { priv->adapter->tx_lock_flag = false; if (ptx_pd) ptx_pd->flags = 0; @@ -278,7 +278,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, case -1: adapter->data_sent = false; dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", - __func__, ret); + __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb_aggr, ret); return 0; diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 681d3f2a4c2..9c44088054d 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -27,31 +27,31 @@ #include "11n_rxreorder.h" /* - * This function dispatches all packets in the Rx reorder table. + * This function dispatches all packets in the Rx reorder table until the + * start window. * * There could be holes in the buffer, which are skipped by the function. * Since the buffer is linear, the function uses rotation to simulate * circular buffer. */ static void -mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl - *rx_reor_tbl_ptr, int start_win) +mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *tbl, int start_win) { - int no_pkt_to_send, i; + int pkt_to_send, i; void *rx_tmp_ptr; unsigned long flags; - no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ? - min((start_win - rx_reor_tbl_ptr->start_win), - rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size; + pkt_to_send = (start_win > tbl->start_win) ? + min((start_win - tbl->start_win), tbl->win_size) : + tbl->win_size; - for (i = 0; i < no_pkt_to_send; ++i) { + for (i = 0; i < pkt_to_send; ++i) { spin_lock_irqsave(&priv->rx_pkt_lock, flags); rx_tmp_ptr = NULL; - if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) { - rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; - rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + if (tbl->rx_reorder_ptr[i]) { + rx_tmp_ptr = tbl->rx_reorder_ptr[i]; + tbl->rx_reorder_ptr[i] = NULL; } spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); if (rx_tmp_ptr) @@ -63,13 +63,12 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, * We don't have a circular buffer, hence use rotation to simulate * circular buffer */ - for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) { - rx_reor_tbl_ptr->rx_reorder_ptr[i] = - rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i]; - rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL; + for (i = 0; i < tbl->win_size - pkt_to_send; ++i) { + tbl->rx_reorder_ptr[i] = tbl->rx_reorder_ptr[pkt_to_send + i]; + tbl->rx_reorder_ptr[pkt_to_send + i] = NULL; } - rx_reor_tbl_ptr->start_win = start_win; + tbl->start_win = start_win; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); } @@ -83,20 +82,20 @@ mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv, */ static void mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr) + struct mwifiex_rx_reorder_tbl *tbl) { int i, j, xchg; void *rx_tmp_ptr; unsigned long flags; - for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) { + for (i = 0; i < tbl->win_size; ++i) { spin_lock_irqsave(&priv->rx_pkt_lock, flags); - if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) { + if (!tbl->rx_reorder_ptr[i]) { spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); break; } - rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i]; - rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL; + rx_tmp_ptr = tbl->rx_reorder_ptr[i]; + tbl->rx_reorder_ptr[i] = NULL; spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr); } @@ -107,15 +106,13 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, * circular buffer */ if (i > 0) { - xchg = rx_reor_tbl_ptr->win_size - i; + xchg = tbl->win_size - i; for (j = 0; j < xchg; ++j) { - rx_reor_tbl_ptr->rx_reorder_ptr[j] = - rx_reor_tbl_ptr->rx_reorder_ptr[i + j]; - rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL; + tbl->rx_reorder_ptr[j] = tbl->rx_reorder_ptr[i + j]; + tbl->rx_reorder_ptr[i + j] = NULL; } } - rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i) - &(MAX_TID_VALUE - 1); + tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1); spin_unlock_irqrestore(&priv->rx_pkt_lock, flags); } @@ -126,28 +123,25 @@ mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, * pending packets in the Rx reorder table before deletion. */ static void -mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, - struct mwifiex_rx_reorder_tbl - *rx_reor_tbl_ptr) +mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, + struct mwifiex_rx_reorder_tbl *tbl) { unsigned long flags; - if (!rx_reor_tbl_ptr) + if (!tbl) return; - mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, - (rx_reor_tbl_ptr->start_win + - rx_reor_tbl_ptr->win_size) - &(MAX_TID_VALUE - 1)); + mwifiex_11n_dispatch_pkt(priv, tbl, (tbl->start_win + tbl->win_size) & + (MAX_TID_VALUE - 1)); - del_timer(&rx_reor_tbl_ptr->timer_context.timer); + del_timer(&tbl->timer_context.timer); spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); - list_del(&rx_reor_tbl_ptr->list); + list_del(&tbl->list); spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - kfree(rx_reor_tbl_ptr->rx_reorder_ptr); - kfree(rx_reor_tbl_ptr); + kfree(tbl->rx_reorder_ptr); + kfree(tbl); } /* @@ -157,16 +151,15 @@ mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv, static struct mwifiex_rx_reorder_tbl * mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; unsigned long flags; spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); - list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) { - if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN)) - && (rx_reor_tbl_ptr->tid == tid)) { + list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) { + if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) { spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - return rx_reor_tbl_ptr; + return tbl; } } spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); @@ -200,19 +193,19 @@ mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr) static void mwifiex_flush_data(unsigned long context) { - struct reorder_tmr_cnxt *reorder_cnxt = + struct reorder_tmr_cnxt *ctx = (struct reorder_tmr_cnxt *) context; int start_win; - start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr); - if (start_win >= 0) { - dev_dbg(reorder_cnxt->priv->adapter->dev, - "info: flush data %d\n", start_win); - mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv, - reorder_cnxt->ptr, - ((reorder_cnxt->ptr->start_win + - start_win + 1) & (MAX_TID_VALUE - 1))); - } + start_win = mwifiex_11n_find_last_seq_num(ctx->ptr); + + if (start_win < 0) + return; + + dev_dbg(ctx->priv->adapter->dev, "info: flush data %d\n", start_win); + mwifiex_11n_dispatch_pkt(ctx->priv, ctx->ptr, + (ctx->ptr->start_win + start_win + 1) & + (MAX_TID_VALUE - 1)); } /* @@ -227,10 +220,10 @@ mwifiex_flush_data(unsigned long context) */ static void mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, - int tid, int win_size, int seq_num) + int tid, int win_size, int seq_num) { int i; - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node; + struct mwifiex_rx_reorder_tbl *tbl, *new_node; u16 last_seq = 0; unsigned long flags; @@ -238,17 +231,16 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, * If we get a TID, ta pair which is already present dispatch all the * the packets and move the window size until the ssn */ - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); - if (rx_reor_tbl_ptr) { - mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr, - seq_num); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta); + if (tbl) { + mwifiex_11n_dispatch_pkt(priv, tbl, seq_num); return; } - /* if !rx_reor_tbl_ptr then create one */ + /* if !tbl then create one */ new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); if (!new_node) { dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n", - __func__); + __func__); return; } @@ -360,7 +352,8 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv, cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set); mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr, - tid, win_size, le16_to_cpu(cmd_addba_req->ssn)); + tid, win_size, + le16_to_cpu(cmd_addba_req->ssn)); return 0; } @@ -401,35 +394,34 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, u16 seq_num, u16 tid, u8 *ta, u8 pkt_type, void *payload) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; int start_win, end_win, win_size; u16 pkt_index; - rx_reor_tbl_ptr = - mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, - tid, ta); - if (!rx_reor_tbl_ptr) { + tbl = mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv, + tid, ta); + if (!tbl) { if (pkt_type != PKT_TYPE_BAR) mwifiex_process_rx_packet(priv->adapter, payload); return 0; } - start_win = rx_reor_tbl_ptr->start_win; - win_size = rx_reor_tbl_ptr->win_size; + start_win = tbl->start_win; + win_size = tbl->win_size; end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1); - del_timer(&rx_reor_tbl_ptr->timer_context.timer); - mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies - + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); + del_timer(&tbl->timer_context.timer); + mod_timer(&tbl->timer_context.timer, + jiffies + (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000); /* * If seq_num is less then starting win then ignore and drop the * packet */ if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */ - if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1)) - && (seq_num < start_win)) + if (seq_num >= ((start_win + TWOPOW11) & + (MAX_TID_VALUE - 1)) && (seq_num < start_win)) return -1; - } else if ((seq_num < start_win) - || (seq_num > (start_win + (TWOPOW11)))) { + } else if ((seq_num < start_win) || + (seq_num > (start_win + TWOPOW11))) { return -1; } @@ -440,17 +432,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, if (pkt_type == PKT_TYPE_BAR) seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1); - if (((end_win < start_win) - && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) - && (seq_num > end_win)) || ((end_win > start_win) - && ((seq_num > end_win) || (seq_num < start_win)))) { + if (((end_win < start_win) && + (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win))) && + (seq_num > end_win)) || + ((end_win > start_win) && ((seq_num > end_win) || + (seq_num < start_win)))) { end_win = seq_num; if (((seq_num - win_size) + 1) >= 0) start_win = (end_win - win_size) + 1; else start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1; - mwifiex_11n_dispatch_pkt_until_start_win(priv, - rx_reor_tbl_ptr, start_win); + mwifiex_11n_dispatch_pkt(priv, tbl, start_win); } if (pkt_type != PKT_TYPE_BAR) { @@ -459,17 +451,17 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, else pkt_index = (seq_num+MAX_TID_VALUE) - start_win; - if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index]) + if (tbl->rx_reorder_ptr[pkt_index]) return -1; - rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload; + tbl->rx_reorder_ptr[pkt_index] = payload; } /* * Dispatch all packets sequentially from start_win until a * hole is found and adjust the start_win appropriately */ - mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr); + mwifiex_11n_scan_and_dispatch(priv, tbl); return 0; } @@ -480,10 +472,10 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv, * The TID/TA are taken from del BA event body. */ void -mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, - u8 *peer_mac, u8 type, int initiator) +mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac, + u8 type, int initiator) { - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; struct mwifiex_tx_ba_stream_tbl *ptx_tbl; u8 cleanup_rx_reorder_tbl; unsigned long flags; @@ -493,23 +485,23 @@ mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid, else cleanup_rx_reorder_tbl = (initiator) ? false : true; - dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, " - "initiator=%d\n", peer_mac, tid, initiator); + dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d initiator=%d\n", + peer_mac, tid, initiator); if (cleanup_rx_reorder_tbl) { - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, peer_mac); - if (!rx_reor_tbl_ptr) { + if (!tbl) { dev_dbg(priv->adapter->dev, - "event: TID, TA not found in table\n"); + "event: TID, TA not found in table\n"); return; } - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr); + mwifiex_del_rx_reorder_entry(priv, tbl); } else { - ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac); + ptx_tbl = mwifiex_get_ba_tbl(priv, tid, peer_mac); if (!ptx_tbl) { dev_dbg(priv->adapter->dev, - "event: TID, RA not found in table\n"); + "event: TID, RA not found in table\n"); return; } @@ -532,7 +524,7 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, (struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp; int tid, win_size; - struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr; + struct mwifiex_rx_reorder_tbl *tbl; uint16_t block_ack_param_set; block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); @@ -548,19 +540,18 @@ int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> BLOCKACKPARAM_WINSIZE_POS; - dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM" - " tid=%d ssn=%d win_size=%d\n", - add_ba_rsp->peer_mac_addr, - tid, add_ba_rsp->ssn, win_size); + dev_dbg(priv->adapter->dev, + "cmd: ADDBA RSP: %pM tid=%d ssn=%d win_size=%d\n", + add_ba_rsp->peer_mac_addr, tid, + add_ba_rsp->ssn, win_size); } else { dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n", - add_ba_rsp->peer_mac_addr, tid); + add_ba_rsp->peer_mac_addr, tid); - rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, - tid, add_ba_rsp->peer_mac_addr); - if (rx_reor_tbl_ptr) - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, - rx_reor_tbl_ptr); + tbl = mwifiex_11n_get_rx_reorder_tbl(priv, tid, + add_ba_rsp->peer_mac_addr); + if (tbl) + mwifiex_del_rx_reorder_entry(priv, tbl); } return 0; @@ -599,7 +590,7 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) list_for_each_entry_safe(del_tbl_ptr, tmp_node, &priv->rx_reorder_tbl_ptr, list) { spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); - mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr); + mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr); spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); } spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index 033c8adbdcd..f1bffebabc6 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -41,9 +41,8 @@ int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, u8 pkttype, void *payload); -void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid, - u8 *PeerMACAddr, u8 type, - int initiator); +void mwifiex_del_ba_tbl(struct mwifiex_private *priv, int Tid, + u8 *PeerMACAddr, u8 type, int initiator); void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, struct host_cmd_ds_11n_batimeout *event); int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv, diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 2210a0f9af2..65050384c42 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -79,7 +79,7 @@ static int mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { wiphy_err(wiphy, "deleting the crypto keys\n"); @@ -122,13 +122,12 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); u32 ps_mode; if (timeout) wiphy_dbg(wiphy, - "info: ignoring the timeout value" - " for IEEE power save\n"); + "info: ignore timeout value for IEEE Power Save\n"); ps_mode = enabled; @@ -143,10 +142,10 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool unicast, bool multicast) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); /* Return if WEP key not configured */ - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) + if (!priv->sec_info.wep_enabled) return 0; if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) { @@ -165,10 +164,10 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, params->key, params->key_len, - key_index, 0)) { + key_index, 0)) { wiphy_err(wiphy, "crypto keys added\n"); return -EFAULT; } @@ -225,7 +224,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) } if (ch->hw_value == next_chan + 1 && - ch->max_power == max_pwr) { + ch->max_power == max_pwr) { next_chan++; no_of_parsed_chan++; } else { @@ -252,7 +251,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) domain_info->no_of_triplet = no_of_triplet; if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, - HostCmd_ACT_GEN_SET, 0, NULL)) { + HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "11D: setting domain info in FW\n"); return -1; } @@ -271,7 +270,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) * - Set bt Country IE */ static int mwifiex_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) + struct regulatory_request *request) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); @@ -316,7 +315,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (chan->band == IEEE80211_BAND_2GHZ) { if (channel_type == NL80211_CHAN_NO_HT) if (priv->adapter->config_bands == BAND_B || - priv->adapter->config_bands == BAND_G) + priv->adapter->config_bands == BAND_G) config_bands = priv->adapter->config_bands; else @@ -336,7 +335,7 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { adapter->adhoc_start_band = config_bands; if ((config_bands & BAND_GN) || - (config_bands & BAND_AN)) + (config_bands & BAND_AN)) adapter->adhoc_11n_enabled = true; else adapter->adhoc_11n_enabled = false; @@ -350,9 +349,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, mwifiex_send_domain_info_cmd_fw(wiphy); } - wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and " - "mode %d\n", config_bands, adapter->sec_chan_offset, - priv->bss_mode); + wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", + config_bands, adapter->sec_chan_offset, priv->bss_mode); if (!chan) return 0; @@ -376,7 +374,12 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv; + + if (dev) + priv = mwifiex_netdev_get_priv(dev); + else + priv = mwifiex_cfg80211_get_priv(wiphy); if (priv->media_connected) { wiphy_err(wiphy, "This setting is valid only when station " @@ -398,8 +401,8 @@ mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) { int ret; - if (frag_thr < MWIFIEX_FRAG_MIN_VALUE - || frag_thr > MWIFIEX_FRAG_MAX_VALUE) + if (frag_thr < MWIFIEX_FRAG_MIN_VALUE || + frag_thr > MWIFIEX_FRAG_MAX_VALUE) return -EINVAL; /* Send request to firmware */ @@ -534,6 +537,11 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, ret = -EFAULT; } + /* Get DTIM period information from firmware */ + mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB, + HostCmd_ACT_GEN_GET, DTIM_PERIOD_I, + &priv->dtim_period); + /* * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid * MCS index values for us are 0 to 7. @@ -557,6 +565,22 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */ sinfo->txrate.legacy = rate.rate * 5; + if (priv->bss_mode == NL80211_IFTYPE_STATION) { + sinfo->filled |= STATION_INFO_BSS_PARAM; + sinfo->bss_param.flags = 0; + if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & + WLAN_CAPABILITY_SHORT_PREAMBLE) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & + WLAN_CAPABILITY_SHORT_SLOT_TIME) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.dtim_period = priv->dtim_period; + sinfo->bss_param.beacon_interval = + priv->curr_bss_params.bss_descriptor.beacon_period; + } + return ret; } @@ -587,7 +611,6 @@ static struct ieee80211_rate mwifiex_rates[] = { {.bitrate = 20, .hw_value = 4, }, {.bitrate = 55, .hw_value = 11, }, {.bitrate = 110, .hw_value = 22, }, - {.bitrate = 220, .hw_value = 44, }, {.bitrate = 60, .hw_value = 12, }, {.bitrate = 90, .hw_value = 18, }, {.bitrate = 120, .hw_value = 24, }, @@ -596,7 +619,6 @@ static struct ieee80211_rate mwifiex_rates[] = { {.bitrate = 360, .hw_value = 72, }, {.bitrate = 480, .hw_value = 96, }, {.bitrate = 540, .hw_value = 108, }, - {.bitrate = 720, .hw_value = 144, }, }; /* Channel definitions to be advertised to cfg80211 */ @@ -622,7 +644,7 @@ static struct ieee80211_supported_band mwifiex_band_2ghz = { .channels = mwifiex_channels_2ghz, .n_channels = ARRAY_SIZE(mwifiex_channels_2ghz), .bitrates = mwifiex_rates, - .n_bitrates = 14, + .n_bitrates = ARRAY_SIZE(mwifiex_rates), }; static struct ieee80211_channel mwifiex_channels_5ghz[] = { @@ -662,8 +684,8 @@ static struct ieee80211_channel mwifiex_channels_5ghz[] = { static struct ieee80211_supported_band mwifiex_band_5ghz = { .channels = mwifiex_channels_5ghz, .n_channels = ARRAY_SIZE(mwifiex_channels_5ghz), - .bitrates = mwifiex_rates - 4, - .n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4, + .bitrates = mwifiex_rates + 4, + .n_bitrates = ARRAY_SIZE(mwifiex_rates) - 4, }; @@ -722,8 +744,7 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, adapter->channel_type = NL80211_CHAN_NO_HT; wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", - (mode & BAND_B) ? "b" : "", - (mode & BAND_G) ? "g" : ""); + (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); return 0; } @@ -778,8 +799,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) ie_buf[1] = bss_info.ssid.ssid_len; memcpy(&ie_buf[sizeof(struct ieee_types_header)], - &bss_info.ssid.ssid, - bss_info.ssid.ssid_len); + &bss_info.ssid.ssid, bss_info.ssid.ssid_len); ie_len = ie_buf[1] + sizeof(struct ieee_types_header); band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); @@ -788,8 +808,8 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) band)); bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, - bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, - 0, ie_buf, ie_len, 0, GFP_KERNEL); + bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, + 0, ie_buf, ie_len, 0, GFP_KERNEL); cfg80211_put_bss(bss); memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); @@ -815,12 +835,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, u8 *bssid, int mode, struct ieee80211_channel *channel, struct cfg80211_connect_params *sme, bool privacy) { - struct mwifiex_802_11_ssid req_ssid; + struct cfg80211_ssid req_ssid; int ret, auth_type = 0; struct cfg80211_bss *bss = NULL; u8 is_scanning_required = 0; - memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); + memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); req_ssid.ssid_len = ssid_len; if (ssid_len > IEEE80211_MAX_SSID_LEN) { @@ -847,6 +867,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, priv->sec_info.wpa2_enabled = false; priv->wep_key_curr_index = 0; priv->sec_info.encryption_mode = 0; + priv->sec_info.is_authtype_auto = 0; ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); if (mode == NL80211_IFTYPE_ADHOC) { @@ -868,11 +889,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } /* Now handle infra mode. "sme" is valid for infra mode only */ - if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC - || sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) + if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM; - else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) - auth_type = NL80211_AUTHTYPE_SHARED_KEY; + priv->sec_info.is_authtype_auto = 1; + } else { + auth_type = sme->auth_type; + } if (sme->crypto.n_ciphers_pairwise) { priv->sec_info.encryption_mode = @@ -898,12 +920,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, } } done: - /* Do specific SSID scanning */ - if (mwifiex_request_scan(priv, &req_ssid)) { - dev_err(priv->adapter->dev, "scan error\n"); - return -EFAULT; - } - /* * Scan entries are valid for some time (15 sec). So we can save one * active scan time if we just try cfg80211_get_bss first. If it fails @@ -932,14 +948,15 @@ done: if (!bss) { if (is_scanning_required) { - dev_warn(priv->adapter->dev, "assoc: requested " - "bss not found in scan results\n"); + dev_warn(priv->adapter->dev, + "assoc: requested bss not found in scan results\n"); break; } is_scanning_required = 1; } else { - dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", - (char *) req_ssid.ssid, bss->bssid); + dev_dbg(priv->adapter->dev, + "info: trying to associate to '%s' bssid %pM\n", + (char *) req_ssid.ssid, bss->bssid); memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN); break; } @@ -979,7 +996,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", - (char *) sme->ssid, sme->bssid); + (char *) sme->ssid, sme->bssid); ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, priv->bss_mode, sme->channel, sme, 0); @@ -1011,7 +1028,7 @@ static int mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int ret = 0; if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { @@ -1021,11 +1038,11 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", - (char *) params->ssid, params->bssid); + (char *) params->ssid, params->bssid); ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, - params->bssid, priv->bss_mode, - params->channel, NULL, params->privacy); + params->bssid, priv->bss_mode, + params->channel, NULL, params->privacy); done: if (!ret) { cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); @@ -1049,10 +1066,10 @@ done: static int mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", - priv->cfg_bssid); + priv->cfg_bssid); if (mwifiex_deauthenticate(priv, NULL)) return -EFAULT; @@ -1081,17 +1098,15 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, priv->scan_request = request; priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), - GFP_KERNEL); + GFP_KERNEL); if (!priv->user_scan_cfg) { dev_err(priv->adapter->dev, "failed to alloc scan_req\n"); return -ENOMEM; } - for (i = 0; i < request->n_ssids; i++) { - memcpy(priv->user_scan_cfg->ssid_list[i].ssid, - request->ssids[i].ssid, request->ssids[i].ssid_len); - priv->user_scan_cfg->ssid_list[i].max_len = - request->ssids[i].ssid_len; - } + + priv->user_scan_cfg->num_ssids = request->n_ssids; + priv->user_scan_cfg->ssid_list = request->ssids; + for (i = 0; i < request->n_channels; i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; @@ -1099,10 +1114,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) priv->user_scan_cfg->chan_list[i].scan_type = - MWIFIEX_SCAN_TYPE_PASSIVE; + MWIFIEX_SCAN_TYPE_PASSIVE; else priv->user_scan_cfg->chan_list[i].scan_type = - MWIFIEX_SCAN_TYPE_ACTIVE; + MWIFIEX_SCAN_TYPE_ACTIVE; priv->user_scan_cfg->chan_list[i].scan_time = 0; } @@ -1173,9 +1188,9 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, memset(mcs, 0xff, rx_mcs_supp); /* Clear all the other values */ memset(&mcs[rx_mcs_supp], 0, - sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); + sizeof(struct ieee80211_mcs_info) - rx_mcs_supp); if (priv->bss_mode == NL80211_IFTYPE_STATION || - ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) + ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap)) /* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */ SETHT_MCS32(mcs_set.rx_mask); @@ -1188,10 +1203,10 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, * create a new virtual interface with the given name */ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, - char *name, - enum nl80211_iftype type, - u32 *flags, - struct vif_params *params) + char *name, + enum nl80211_iftype type, + u32 *flags, + struct vif_params *params) { struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_adapter *adapter; @@ -1224,7 +1239,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_index = 0; priv->bss_num = 0; break; @@ -1288,10 +1302,7 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); */ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - - if (!priv || !dev) - return 0; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_remove(priv); @@ -1353,11 +1364,12 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) int ret; void *wdev_priv; struct wireless_dev *wdev; + struct ieee80211_sta_ht_cap *ht_info; wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) { dev_err(priv->adapter->dev, "%s: allocating wireless device\n", - __func__); + __func__); return -ENOMEM; } wdev->wiphy = @@ -1369,17 +1381,17 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) } wdev->iftype = NL80211_IFTYPE_STATION; wdev->wiphy->max_scan_ssids = 10; - wdev->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); + wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; - mwifiex_setup_ht_caps( - &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv); + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); if (priv->adapter->config_bands & BAND_A) { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; - mwifiex_setup_ht_caps( - &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv); + ht_info = &wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap; + mwifiex_setup_ht_caps(ht_info, priv); } else { wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; } @@ -1406,13 +1418,13 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) ret = wiphy_register(wdev->wiphy); if (ret < 0) { dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", - __func__); + __func__); wiphy_free(wdev->wiphy); kfree(wdev); return ret; } else { dev_dbg(priv->adapter->dev, - "info: successfully registered wiphy device\n"); + "info: successfully registered wiphy device\n"); } priv->wdev = wdev; diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 1782a77f15d..2fe1c33765b 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c @@ -163,65 +163,24 @@ u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates) return mwifiex_get_supported_rates(priv, rates); else return mwifiex_copy_rates(rates, 0, - priv->curr_bss_params.data_rates, - priv->curr_bss_params.num_of_rates); + priv->curr_bss_params.data_rates, + priv->curr_bss_params.num_of_rates); } /* * This function locates the Channel-Frequency-Power triplet based upon - * band and channel parameters. + * band and channel/frequency parameters. */ struct mwifiex_chan_freq_power * -mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private - *priv, u8 band, u16 channel) +mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq) { struct mwifiex_chan_freq_power *cfp = NULL; struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; + struct ieee80211_channel *ch = NULL; int i; - if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) - sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; - else - sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; - - if (!sband) { - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & channel %d\n", __func__, band, channel); + if (!channel && !freq) return cfp; - } - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - if (((ch->hw_value == channel) || - (channel == FIRST_VALID_CHANNEL)) - && !(ch->flags & IEEE80211_CHAN_DISABLED)) { - priv->cfp.channel = channel; - priv->cfp.freq = ch->center_freq; - priv->cfp.max_tx_power = ch->max_power; - cfp = &priv->cfp; - break; - } - } - if (i == sband->n_channels) - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & channel %d\n", __func__, band, channel); - - return cfp; -} - -/* - * This function locates the Channel-Frequency-Power triplet based upon - * band and frequency parameters. - */ -struct mwifiex_chan_freq_power * -mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, - u8 band, u32 freq) -{ - struct mwifiex_chan_freq_power *cfp = NULL; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - int i; if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; @@ -229,25 +188,40 @@ mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv, sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; if (!sband) { - dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & freq %d\n", __func__, band, freq); + dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n", + __func__, band); return cfp; } for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; - if ((ch->center_freq == freq) && - !(ch->flags & IEEE80211_CHAN_DISABLED)) { - priv->cfp.channel = ch->hw_value; - priv->cfp.freq = freq; - priv->cfp.max_tx_power = ch->max_power; - cfp = &priv->cfp; - break; + + if (ch->flags & IEEE80211_CHAN_DISABLED) + continue; + + if (freq) { + if (ch->center_freq == freq) + break; + } else { + /* find by valid channel*/ + if (ch->hw_value == channel || + channel == FIRST_VALID_CHANNEL) + break; } } - if (i == sband->n_channels) + if (i == sband->n_channels) { dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d" - " & freq %d\n", __func__, band, freq); + " & channel=%d freq=%d\n", __func__, band, channel, + freq); + } else { + if (!ch) + return cfp; + + priv->cfp.channel = ch->hw_value; + priv->cfp.freq = ch->center_freq; + priv->cfp.max_tx_power = ch->max_power; + cfp = &priv->cfp; + } return cfp; } diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6e0a3eaecf7..07f6e009255 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -67,7 +67,7 @@ mwifiex_get_cmd_node(struct mwifiex_adapter *adapter) return NULL; } cmd_node = list_first_entry(&adapter->cmd_free_q, - struct cmd_ctrl_node, list); + struct cmd_ctrl_node, list); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags); @@ -158,8 +158,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, /* Set command sequence number */ adapter->seq_num++; host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO - (adapter->seq_num, cmd_node->priv->bss_num, - cmd_node->priv->bss_type)); + (adapter->seq_num, + cmd_node->priv->bss_num, + cmd_node->priv->bss_type)); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = cmd_node; @@ -174,8 +175,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," " seqno %#x\n", tstamp.tv_sec, tstamp.tv_usec, cmd_code, - le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, - le16_to_cpu(host_cmd->seq_num)); + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size, + le16_to_cpu(host_cmd->seq_num)); skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN); @@ -200,17 +201,17 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, /* Save the last command id and action to debug log */ adapter->dbg.last_cmd_index = - (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM; adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code; adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] = - le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); + le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)); /* Clear BSS_NO_BITS from HostCmd */ cmd_code &= HostCmd_CMD_ID_MASK; /* Setup the timer after transmit command */ mod_timer(&adapter->cmd_timer, - jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); + jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000); return 0; } @@ -230,7 +231,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) struct mwifiex_private *priv; struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) - adapter->sleep_cfm->data; + adapter->sleep_cfm->data; priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); sleep_cfm_buf->seq_num = @@ -250,7 +251,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) return -1; } if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) - == MWIFIEX_BSS_ROLE_STA) { + == MWIFIEX_BSS_ROLE_STA) { if (!sleep_cfm_buf->resp_ctrl) /* Response is not needed for sleep confirm command */ @@ -258,12 +259,12 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter) else adapter->ps_state = PS_STATE_SLEEP_CFM; - if (!sleep_cfm_buf->resp_ctrl - && (adapter->is_hs_configured - && !adapter->sleep_period.period)) { + if (!sleep_cfm_buf->resp_ctrl && + (adapter->is_hs_configured && + !adapter->sleep_period.period)) { adapter->pm_wakeup_card_req = true; - mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_STA), true); + mwifiex_hs_activated_event(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_STA), true); } } @@ -293,7 +294,7 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) cmd_array = kzalloc(buf_size, GFP_KERNEL); if (!cmd_array) { dev_err(adapter->dev, "%s: failed to alloc cmd_array\n", - __func__); + __func__); return -ENOMEM; } @@ -376,9 +377,9 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) /* Save the last event to debug log */ adapter->dbg.last_event_index = - (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM; adapter->dbg.last_event[adapter->dbg.last_event_index] = - (u16) eventcause; + (u16) eventcause; /* Get BSS number and corresponding priv */ priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause), @@ -391,13 +392,14 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) if (skb) { rx_info = MWIFIEX_SKB_RXCB(skb); - rx_info->bss_index = priv->bss_index; + rx_info->bss_num = priv->bss_num; + rx_info->bss_type = priv->bss_type; } if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", - tstamp.tv_sec, tstamp.tv_usec, eventcause); + tstamp.tv_sec, tstamp.tv_usec, eventcause); } ret = mwifiex_process_sta_event(priv); @@ -508,7 +510,7 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, /* Return error, since the command preparation failed */ if (ret) { dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n", - cmd_no); + cmd_no); mwifiex_insert_cmd_to_free_q(adapter, cmd_node); return -1; } @@ -576,9 +578,9 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter, /* Exit_PS command needs to be queued in the header always. */ if (command == HostCmd_CMD_802_11_PS_MODE_ENH) { struct host_cmd_ds_802_11_ps_mode_enh *pm = - &host_cmd->params.psmode_enh; - if ((le16_to_cpu(pm->action) == DIS_PS) - || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { + &host_cmd->params.psmode_enh; + if ((le16_to_cpu(pm->action) == DIS_PS) || + (le16_to_cpu(pm->action) == DIS_AUTO_PS)) { if (adapter->ps_state != PS_STATE_AWAKE) add_tail = false; } @@ -691,7 +693,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) { resp = (struct host_cmd_ds_command *) adapter->upld_buf; dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n", - le16_to_cpu(resp->command)); + le16_to_cpu(resp->command)); return -1; } @@ -700,7 +702,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data; if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) { dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n", - le16_to_cpu(resp->command)); + le16_to_cpu(resp->command)); mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); adapter->curr_cmd = NULL; @@ -724,8 +726,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Get BSS number and corresponding priv */ priv = mwifiex_get_priv_by_id(adapter, - HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), - HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); + HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)), + HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num))); if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); /* Clear RET_BIT from HostCmd */ @@ -736,9 +738,9 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Save the last command response to debug log */ adapter->dbg.last_cmd_resp_index = - (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; + (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM; adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] = - orig_cmdresp_no; + orig_cmdresp_no; do_gettimeofday(&tstamp); dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d," @@ -760,8 +762,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) { adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD; - if ((cmdresp_result == HostCmd_RESULT_OK) - && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) + if ((cmdresp_result == HostCmd_RESULT_OK) && + (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH)) ret = mwifiex_ret_802_11_hs_cfg(priv, resp); } else { /* handle response */ @@ -770,7 +772,7 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) /* Check init command response */ if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) { - if (ret == -1) { + if (ret) { dev_err(adapter->dev, "%s: cmd %#x failed during " "initialization\n", __func__, cmdresp_no); mwifiex_init_fw_complete(adapter); @@ -780,10 +782,8 @@ int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter) } if (adapter->curr_cmd) { - if (adapter->curr_cmd->wait_q_enabled && (!ret)) - adapter->cmd_wait_q.status = 0; - else if (adapter->curr_cmd->wait_q_enabled && (ret == -1)) - adapter->cmd_wait_q.status = -1; + if (adapter->curr_cmd->wait_q_enabled) + adapter->cmd_wait_q.status = ret; /* Clean up and put current command back to cmd_free_q */ mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); @@ -825,44 +825,45 @@ mwifiex_cmd_timeout_func(unsigned long function_context) adapter->dbg.timeout_cmd_act = adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index]; do_gettimeofday(&tstamp); - dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x," - " act = %#x\n", __func__, - tstamp.tv_sec, tstamp.tv_usec, - adapter->dbg.timeout_cmd_id, - adapter->dbg.timeout_cmd_act); + dev_err(adapter->dev, + "%s: Timeout cmd id (%lu.%lu) = %#x, act = %#x\n", + __func__, tstamp.tv_sec, tstamp.tv_usec, + adapter->dbg.timeout_cmd_id, + adapter->dbg.timeout_cmd_act); dev_err(adapter->dev, "num_data_h2c_failure = %d\n", - adapter->dbg.num_tx_host_to_card_failure); + adapter->dbg.num_tx_host_to_card_failure); dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n", - adapter->dbg.num_cmd_host_to_card_failure); + adapter->dbg.num_cmd_host_to_card_failure); dev_err(adapter->dev, "num_cmd_timeout = %d\n", - adapter->dbg.num_cmd_timeout); + adapter->dbg.num_cmd_timeout); dev_err(adapter->dev, "num_tx_timeout = %d\n", - adapter->dbg.num_tx_timeout); + adapter->dbg.num_tx_timeout); dev_err(adapter->dev, "last_cmd_index = %d\n", - adapter->dbg.last_cmd_index); + adapter->dbg.last_cmd_index); print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_id, DBG_CMD_NUM); + adapter->dbg.last_cmd_id, DBG_CMD_NUM); print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_act, DBG_CMD_NUM); + adapter->dbg.last_cmd_act, DBG_CMD_NUM); dev_err(adapter->dev, "last_cmd_resp_index = %d\n", - adapter->dbg.last_cmd_resp_index); + adapter->dbg.last_cmd_resp_index); print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM); + adapter->dbg.last_cmd_resp_id, + DBG_CMD_NUM); dev_err(adapter->dev, "last_event_index = %d\n", - adapter->dbg.last_event_index); + adapter->dbg.last_event_index); print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET, - adapter->dbg.last_event, DBG_CMD_NUM); + adapter->dbg.last_event, DBG_CMD_NUM); dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n", - adapter->data_sent, adapter->cmd_sent); + adapter->data_sent, adapter->cmd_sent); dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", - adapter->ps_mode, adapter->ps_state); + adapter->ps_mode, adapter->ps_state); } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); @@ -943,7 +944,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) uint16_t cancel_scan_cmd = false; if ((adapter->curr_cmd) && - (adapter->curr_cmd->wait_q_enabled)) { + (adapter->curr_cmd->wait_q_enabled)) { spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); cmd_node = adapter->curr_cmd; cmd_node->wait_q_enabled = false; @@ -997,9 +998,9 @@ mwifiex_check_ps_cond(struct mwifiex_adapter *adapter) else dev_dbg(adapter->dev, "cmd: Delay Sleep Confirm (%s%s%s)\n", - (adapter->cmd_sent) ? "D" : "", - (adapter->curr_cmd) ? "C" : "", - (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); + (adapter->cmd_sent) ? "D" : "", + (adapter->curr_cmd) ? "C" : "", + (IS_CARD_RX_RCVD(adapter)) ? "R" : ""); } /* @@ -1051,8 +1052,8 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply" " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n", resp->result, conditions, - phs_cfg->params.hs_config.gpio, - phs_cfg->params.hs_config.gap); + phs_cfg->params.hs_config.gpio, + phs_cfg->params.hs_config.gap); } if (conditions != HOST_SLEEP_CFG_CANCEL) { adapter->is_hs_configured = true; @@ -1079,7 +1080,8 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->hs_activated = false; adapter->is_hs_configured = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), false); + MWIFIEX_BSS_ROLE_ANY), + false); } /* @@ -1115,22 +1117,24 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter, command &= HostCmd_CMD_ID_MASK; if (command != HostCmd_CMD_802_11_PS_MODE_ENH) { - dev_err(adapter->dev, "%s: received unexpected response for" - " cmd %x, result = %x\n", __func__, command, result); + dev_err(adapter->dev, + "%s: rcvd unexpected resp for cmd %#x, result = %x\n", + __func__, command, result); return; } if (result) { dev_err(adapter->dev, "%s: sleep confirm cmd failed\n", - __func__); + __func__); adapter->pm_wakeup_card_req = false; adapter->ps_state = PS_STATE_AWAKE; return; } adapter->pm_wakeup_card_req = true; if (adapter->is_hs_configured) - mwifiex_hs_activated_event(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), true); + mwifiex_hs_activated_event(mwifiex_get_priv + (adapter, MWIFIEX_BSS_ROLE_ANY), + true); adapter->ps_state = PS_STATE_SLEEP; cmd->command = cpu_to_le16(command); cmd->seq_num = cpu_to_le16(seq_num); @@ -1164,17 +1168,17 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, psmode_enh->action = cpu_to_le16(DIS_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap)); + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == GET_PS) { psmode_enh->action = cpu_to_le16(GET_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap)); + sizeof(psmode_enh->params.ps_bitmap)); } else if (cmd_action == EN_AUTO_PS) { psmode_enh->action = cpu_to_le16(EN_AUTO_PS); psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap); cmd_size = S_DS_GEN + sizeof(psmode_enh->action) + - sizeof(psmode_enh->params.ps_bitmap); + sizeof(psmode_enh->params.ps_bitmap); tlv = (u8 *) cmd + cmd_size; if (ps_bitmap & BITMAP_STA_PS) { struct mwifiex_adapter *adapter = priv->adapter; @@ -1188,19 +1192,18 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, tlv += sizeof(*ps_tlv); dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n"); ps_mode->null_pkt_interval = - cpu_to_le16(adapter->null_pkt_interval); + cpu_to_le16(adapter->null_pkt_interval); ps_mode->multiple_dtims = - cpu_to_le16(adapter->multiple_dtim); + cpu_to_le16(adapter->multiple_dtim); ps_mode->bcn_miss_timeout = - cpu_to_le16(adapter->bcn_miss_time_out); + cpu_to_le16(adapter->bcn_miss_time_out); ps_mode->local_listen_interval = cpu_to_le16(adapter->local_listen_interval); ps_mode->adhoc_wake_period = cpu_to_le16(adapter->adhoc_awake_period); ps_mode->delay_to_ps = - cpu_to_le16(adapter->delay_to_ps); - ps_mode->mode = - cpu_to_le16(adapter->enhanced_ps_mode); + cpu_to_le16(adapter->delay_to_ps); + ps_mode->mode = cpu_to_le16(adapter->enhanced_ps_mode); } if (ps_bitmap & BITMAP_AUTO_DS) { @@ -1218,7 +1221,7 @@ int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv, if (auto_ds) idletime = auto_ds->idle_time; dev_dbg(priv->adapter->dev, - "cmd: PS Command: Enter Auto Deep Sleep\n"); + "cmd: PS Command: Enter Auto Deep Sleep\n"); auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime); } cmd->size = cpu_to_le16(cmd_size); @@ -1245,8 +1248,9 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, uint16_t auto_ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap); - dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", - __func__, resp->result, action); + dev_dbg(adapter->dev, + "info: %s: PS_MODE cmd reply result=%#x action=%#X\n", + __func__, resp->result, action); if (action == EN_AUTO_PS) { if (auto_ps_bitmap & BITMAP_AUTO_DS) { dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n"); @@ -1255,7 +1259,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv, if (auto_ps_bitmap & BITMAP_STA_PS) { dev_dbg(adapter->dev, "cmd: Enabled STA power save\n"); if (adapter->sleep_period.period) - dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n"); + dev_dbg(adapter->dev, + "cmd: set to uapsd/pps mode\n"); } } else if (action == DIS_AUTO_PS) { if (ps_bitmap & BITMAP_AUTO_DS) { @@ -1374,12 +1379,13 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n", - adapter->fw_release_number); + adapter->fw_release_number); dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n", - hw_spec->permanent_addr); - dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", + hw_spec->permanent_addr); + dev_dbg(adapter->dev, + "info: GET_HW_SPEC: hw_if_version=%#x version=%#x\n", le16_to_cpu(hw_spec->hw_if_version), - le16_to_cpu(hw_spec->version)); + le16_to_cpu(hw_spec->version)); if (priv->curr_addr[0] == 0xff) memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN); @@ -1394,7 +1400,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, /* If it's unidentified region code, use the default (USA) */ if (i >= MWIFIEX_MAX_REGION_CODE) { adapter->region_code = 0x10; - dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n"); + dev_dbg(adapter->dev, + "cmd: unknown region code, use default (USA)\n"); } adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap); diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index ae17ce02a3d..be5fd1652e5 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -91,18 +91,14 @@ struct mwifiex_fw_image { u32 fw_len; }; -struct mwifiex_802_11_ssid { - u32 ssid_len; - u8 ssid[IEEE80211_MAX_SSID_LEN]; -}; - struct mwifiex_wait_queue { wait_queue_head_t wait; int status; }; struct mwifiex_rxinfo { - u8 bss_index; + u8 bss_num; + u8 bss_type; struct sk_buff *parent; u8 use_count; }; @@ -110,7 +106,8 @@ struct mwifiex_rxinfo { struct mwifiex_txinfo { u32 status_code; u8 flags; - u8 bss_index; + u8 bss_num; + u8 bss_type; }; enum mwifiex_wmm_ac_e { diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 51c5417c569..e98fc5af73d 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -86,11 +86,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { MWIFIEX_802_11_PRIV_FILTER_8021X_WEP }; -enum MWIFIEX_802_11_WEP_STATUS { - MWIFIEX_802_11_WEP_ENABLED, - MWIFIEX_802_11_WEP_DISABLED, -}; - #define CAL_SNR(RSSI, NF) ((s16)((s16)(RSSI)-(s16)(NF))) #define PROPRIETARY_TLV_BASE_ID 0x0100 @@ -122,8 +117,8 @@ enum MWIFIEX_802_11_WEP_STATUS { #define BA_STREAM_NOT_ALLOWED 0xff #define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \ - priv->adapter->config_bands & BAND_AN) \ - && priv->curr_bss_params.bss_descriptor.bcn_ht_cap) + priv->adapter->config_bands & BAND_AN) && \ + priv->curr_bss_params.bss_descriptor.bcn_ht_cap) #define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\ BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS) @@ -857,11 +852,6 @@ struct mwifiex_user_scan_chan { u32 scan_time; } __packed; -struct mwifiex_user_scan_ssid { - u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; - u8 max_len; -} __packed; - struct mwifiex_user_scan_cfg { /* * BSS mode to be sent in the firmware command @@ -872,8 +862,9 @@ struct mwifiex_user_scan_cfg { u8 reserved; /* BSSID filter sent in the firmware command to limit the results */ u8 specific_bssid[ETH_ALEN]; - /* SSID filter list used in the to limit the scan results */ - struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH]; + /* SSID filter list used in the firmware to limit the scan results */ + struct cfg80211_ssid *ssid_list; + u8 num_ssids; /* Variable number (fixed maximum) of channels to scan up */ struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; } __packed; diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 1d0ec57a014..54bb4839b57 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -35,28 +35,24 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bss_prio; + struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; unsigned long flags; bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); if (!bss_prio) { dev_err(adapter->dev, "%s: failed to alloc bss_prio\n", - __func__); + __func__); return -ENOMEM; } bss_prio->priv = priv; INIT_LIST_HEAD(&bss_prio->list); - if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur) - adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur = - bss_prio; - - spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_lock, flags); - list_add_tail(&bss_prio->list, - &adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_head); - spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority] - .bss_prio_lock, flags); + if (!tbl[priv->bss_priority].bss_prio_cur) + tbl[priv->bss_priority].bss_prio_cur = bss_prio; + + spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags); + list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head); + spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags); return 0; } @@ -82,7 +78,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv) priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR; priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR; - priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED; + priv->sec_info.wep_enabled = 0; priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; priv->sec_info.encryption_mode = 0; for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++) @@ -157,13 +153,13 @@ static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter) ret = mwifiex_alloc_cmd_buffer(adapter); if (ret) { dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n", - __func__); + __func__); return -1; } adapter->sleep_cfm = dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) - + INTF_HEADER_LEN); + + INTF_HEADER_LEN); if (!adapter->sleep_cfm) { dev_err(adapter->dev, "%s: failed to alloc sleep cfm" @@ -280,6 +276,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) adapter->adhoc_awake_period = 0; memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; + adapter->channel_type = NL80211_CHAN_HT20; } /* @@ -519,7 +516,7 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur; struct list_head *head; - spinlock_t *lock; + spinlock_t *lock; /* bss priority lock */ unsigned long flags; for (i = 0; i < adapter->priv_num; ++i) { @@ -527,8 +524,9 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) cur = &adapter->bss_prio_tbl[i].bss_prio_cur; lock = &adapter->bss_prio_tbl[i].bss_prio_lock; dev_dbg(adapter->dev, "info: delete BSS priority table," - " index = %d, i = %d, head = %p, cur = %p\n", - priv->bss_index, i, head, *cur); + " bss_type = %d, bss_num = %d, i = %d," + " head = %p, cur = %p\n", + priv->bss_type, priv->bss_num, i, head, *cur); if (*cur) { spin_lock_irqsave(lock, flags); if (list_empty(head)) { @@ -636,7 +634,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, ret = adapter->if_ops.check_fw_status(adapter, poll_num); if (!ret) { dev_notice(adapter->dev, - "WLAN FW already running! Skip FW download\n"); + "WLAN FW already running! Skip FW download\n"); goto done; } poll_num = MAX_FIRMWARE_POLL_TRIES; @@ -644,8 +642,7 @@ int mwifiex_dnld_fw(struct mwifiex_adapter *adapter, /* Check if we are the winner for downloading FW */ if (!adapter->winner) { dev_notice(adapter->dev, - "Other interface already running!" - " Skip FW download\n"); + "Other intf already running! Skip FW download\n"); poll_num = MAX_MULTI_INTERFACE_POLL_TRIES; goto poll_fw; } diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index d5d81f1fe41..7ca4e8234f3 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h @@ -50,7 +50,7 @@ struct mwifiex_chan_freq { }; struct mwifiex_ssid_bssid { - struct mwifiex_802_11_ssid ssid; + struct cfg80211_ssid ssid; u8 bssid[ETH_ALEN]; }; @@ -122,7 +122,7 @@ struct mwifiex_ver_ext { struct mwifiex_bss_info { u32 bss_mode; - struct mwifiex_802_11_ssid ssid; + struct cfg80211_ssid ssid; u32 bss_chan; u32 region_code; u32 media_connected; diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 0b0eb5efba9..8f9382b9c3c 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -52,8 +52,9 @@ mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer) * parameter buffer pointer. */ if (priv->gen_ie_buf_len) { - dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n", - __func__, priv->gen_ie_buf_len, *buffer); + dev_dbg(priv->adapter->dev, + "info: %s: append generic ie len %d to %p\n", + __func__, priv->gen_ie_buf_len, *buffer); /* Wrap the generic IE buffer with a pass through TLV type */ ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH); @@ -123,8 +124,9 @@ mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer, memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val)); - dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - " - "%016llx\n", __func__, tsf_val, bss_desc->network_tsf); + dev_dbg(priv->adapter->dev, + "info: %s: TSF offset calc: %016llx - %016llx\n", + __func__, tsf_val, bss_desc->network_tsf); memcpy(*buffer, &tsf_val, sizeof(tsf_val)); *buffer += sizeof(tsf_val); @@ -167,7 +169,7 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1, } dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n", - priv->data_rate); + priv->data_rate); if (!priv->is_data_rate_auto) { while (*ptr) { @@ -212,7 +214,7 @@ mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv, card_rates, card_rates_size)) { *out_rates_size = 0; dev_err(priv->adapter->dev, "%s: cannot get common rates\n", - __func__); + __func__); return -1; } @@ -248,7 +250,7 @@ mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer) */ if (priv->wapi_ie_len) { dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n", - priv->wapi_ie_len, *buffer); + priv->wapi_ie_len, *buffer); /* Wrap the generic IE buffer with a pass through TLV type */ ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE); @@ -293,10 +295,10 @@ static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv, le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF); rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]); rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len) - & 0x00FF); + & 0x00FF); if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2)) memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2], - le16_to_cpu(rsn_ie_tlv->header.len)); + le16_to_cpu(rsn_ie_tlv->header.len)); else return -1; @@ -379,7 +381,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID); ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len); memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid, - le16_to_cpu(ssid_tlv->header.len)); + le16_to_cpu(ssid_tlv->header.len)); pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len); phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos; @@ -411,13 +413,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, memcpy(rates_tlv->rates, rates, rates_size); pos += sizeof(rates_tlv->header) + rates_size; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n", - rates_size); + rates_size); /* Add the Authentication type to be used for Auth frames */ auth_tlv = (struct mwifiex_ie_types_auth_type *) pos; auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type)); - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + if (priv->sec_info.wep_enabled) auth_tlv->auth_type = cpu_to_le16( (u16) priv->sec_info.authentication_mode); else @@ -425,12 +427,12 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len); - if (IS_SUPPORT_MULTI_BANDS(priv->adapter) - && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (!bss_desc->disable_11n) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && (bss_desc->bcn_ht_cap) + if (IS_SUPPORT_MULTI_BANDS(priv->adapter) && + !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (!bss_desc->disable_11n) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + (bss_desc->bcn_ht_cap) ) ) { /* Append a channel TLV for the channel the attempted AP was @@ -445,13 +447,13 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, chan_tlv->chan_scan_param[0].chan_number = (bss_desc->phy_param_set.ds_param_set.current_chan); dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + sizeof(struct mwifiex_chan_scan_param_set); } @@ -464,10 +466,10 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, return -1; } - if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (!bss_desc->disable_11n) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (!bss_desc->disable_11n) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN)) mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos); /* Append vendor specific IE TLV */ @@ -493,7 +495,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, tmp_cap &= CAPINFO_MASK; dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", - tmp_cap, CAPINFO_MASK); + tmp_cap, CAPINFO_MASK); assoc->cap_info_bitmap = cpu_to_le16(tmp_cap); return 0; @@ -573,19 +575,19 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN, - sizeof(priv->assoc_rsp_buf)); + sizeof(priv->assoc_rsp_buf)); memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size); if (le16_to_cpu(assoc_rsp->status_code)) { priv->adapter->dbg.num_cmd_assoc_failure++; - dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, " - "status code = %d, error = 0x%x, a_id = 0x%x\n", - le16_to_cpu(assoc_rsp->status_code), - le16_to_cpu(assoc_rsp->cap_info_bitmap), - le16_to_cpu(assoc_rsp->a_id)); + dev_err(priv->adapter->dev, + "ASSOC_RESP: failed, status code=%d err=%#x a_id=%#x\n", + le16_to_cpu(assoc_rsp->status_code), + le16_to_cpu(assoc_rsp->cap_info_bitmap), + le16_to_cpu(assoc_rsp->a_id)); - ret = -1; + ret = le16_to_cpu(assoc_rsp->status_code); goto done; } @@ -600,7 +602,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, bss_desc = priv->attempted_bss_desc; dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, @@ -617,8 +619,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, else priv->curr_bss_params.wmm_enabled = false; - if ((priv->wmm_required || bss_desc->bcn_ht_cap) - && priv->curr_bss_params.wmm_enabled) + if ((priv->wmm_required || bss_desc->bcn_ht_cap) && + priv->curr_bss_params.wmm_enabled) priv->wmm_enabled = true; else priv->wmm_enabled = false; @@ -631,7 +633,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0); dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n", - priv->curr_pkt_filter); + priv->curr_pkt_filter); if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) priv->wpa_is_gtk_set = false; @@ -714,7 +716,7 @@ done: int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { int rsn_ie_len = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -755,7 +757,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n", - adhoc_start->ssid); + adhoc_start->ssid); memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN); memcpy(bss_desc->ssid.ssid, req_ssid->ssid, req_ssid->ssid_len); @@ -777,12 +779,11 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID; adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN; - if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, adapter->adhoc_start_band, (u16) - priv->adhoc_channel)) { + if (!mwifiex_get_cfp(priv, adapter->adhoc_start_band, + (u16) priv->adhoc_channel, 0)) { struct mwifiex_chan_freq_power *cfp; - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - adapter->adhoc_start_band, FIRST_VALID_CHANNEL); + cfp = mwifiex_get_cfp(priv, adapter->adhoc_start_band, + FIRST_VALID_CHANNEL, 0); if (cfp) priv->adhoc_channel = (u8) cfp->channel; } @@ -793,7 +794,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, } dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n", - priv->adhoc_channel); + priv->adhoc_channel); priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel; priv->curr_bss_params.band = adapter->adhoc_start_band; @@ -814,7 +815,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID; adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN; adhoc_start->ss_param_set.ibss_param_set.atim_window - = cpu_to_le16(priv->atim_window); + = cpu_to_le16(priv->atim_window); memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set, sizeof(union ieee_types_ss_param_set)); @@ -842,10 +843,10 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, if ((adapter->adhoc_start_band & BAND_G) && (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) { if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &priv->curr_pkt_filter)) { + HostCmd_ACT_GEN_SET, 0, + &priv->curr_pkt_filter)) { dev_err(adapter->dev, - "ADHOC_S_CMD: G Protection config failed\n"); + "ADHOC_S_CMD: G Protection config failed\n"); return -1; } } @@ -861,8 +862,8 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, &adhoc_start->data_rate, priv->curr_bss_params.num_of_rates); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n", - adhoc_start->data_rate[0], adhoc_start->data_rate[1], - adhoc_start->data_rate[2], adhoc_start->data_rate[3]); + adhoc_start->data_rate[0], adhoc_start->data_rate[1], + adhoc_start->data_rate[2], adhoc_start->data_rate[3]); dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n"); @@ -879,12 +880,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, (u8) priv->curr_bss_params.bss_descriptor.channel; dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type(priv->curr_bss_params.band); - if (adapter->adhoc_start_band & BAND_GN - || adapter->adhoc_start_band & BAND_AN) { + if (adapter->adhoc_start_band & BAND_GN || + adapter->adhoc_start_band & BAND_AN) { if (adapter->sec_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) chan_tlv->chan_scan_param[0].radio_type |= @@ -895,7 +896,7 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, (IEEE80211_HT_PARAM_CHA_SEC_BELOW << 4); } dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + sizeof(struct mwifiex_chan_scan_param_set); cmd_append_size += @@ -926,15 +927,14 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, mwifiex_fill_cap_info(priv, radio_type, ht_cap); pos += sizeof(struct mwifiex_ie_types_htcap); - cmd_append_size += - sizeof(struct mwifiex_ie_types_htcap); + cmd_append_size += sizeof(struct mwifiex_ie_types_htcap); /* Fill HT INFORMATION */ ht_info = (struct mwifiex_ie_types_htinfo *) pos; memset(ht_info, 0, sizeof(struct mwifiex_ie_types_htinfo)); ht_info->header.type = cpu_to_le16(WLAN_EID_HT_INFORMATION); ht_info->header.len = - cpu_to_le16(sizeof(struct ieee80211_ht_info)); + cpu_to_le16(sizeof(struct ieee80211_ht_info)); ht_info->ht_info.control_chan = (u8) priv->curr_bss_params.bss_descriptor.channel; @@ -948,12 +948,12 @@ mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, ht_info->ht_info.basic_set[0] = 0xff; pos += sizeof(struct mwifiex_ie_types_htinfo); cmd_append_size += - sizeof(struct mwifiex_ie_types_htinfo); + sizeof(struct mwifiex_ie_types_htinfo); } - cmd->size = cpu_to_le16((u16) - (sizeof(struct host_cmd_ds_802_11_ad_hoc_start) - + S_DS_GEN + cmd_append_size)); + cmd->size = + cpu_to_le16((u16)(sizeof(struct host_cmd_ds_802_11_ad_hoc_start) + + S_DS_GEN + cmd_append_size)); if (adapter->adhoc_start_band == BAND_B) tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME; @@ -1006,10 +1006,10 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON; if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &curr_pkt_filter)) { + HostCmd_ACT_GEN_SET, 0, + &curr_pkt_filter)) { dev_err(priv->adapter->dev, - "ADHOC_J_CMD: G Protection config failed\n"); + "ADHOC_J_CMD: G Protection config failed\n"); return -1; } } @@ -1040,13 +1040,14 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, tmp_cap &= CAPINFO_MASK; - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X" - " CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK); + dev_dbg(priv->adapter->dev, + "info: ADHOC_J_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n", + tmp_cap, CAPINFO_MASK); /* Information on BSSID descriptor passed to FW */ - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n", - adhoc_join->bss_descriptor.bssid, - adhoc_join->bss_descriptor.ssid); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID=%pM, SSID='%s'\n", + adhoc_join->bss_descriptor.bssid, + adhoc_join->bss_descriptor.ssid); for (i = 0; bss_desc->supported_rates[i] && i < MWIFIEX_SUPPORTED_RATES; @@ -1069,8 +1070,7 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel; priv->curr_bss_params.band = (u8) bss_desc->bss_band; - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED - || priv->sec_info.wpa_enabled) + if (priv->sec_info.wep_enabled || priv->sec_info.wpa_enabled) tmp_cap |= WLAN_CAPABILITY_PRIVACY; if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) { @@ -1084,18 +1084,18 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, sizeof(struct mwifiex_chan_scan_param_set)); chan_tlv->chan_scan_param[0].chan_number = (bss_desc->phy_param_set.ds_param_set.current_chan); - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n", - chan_tlv->chan_scan_param[0].chan_number); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan=%d\n", + chan_tlv->chan_scan_param[0].chan_number); chan_tlv->chan_scan_param[0].radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); - dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n", - chan_tlv->chan_scan_param[0].radio_type); + dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band=%d\n", + chan_tlv->chan_scan_param[0].radio_type); pos += sizeof(chan_tlv->header) + - sizeof(struct mwifiex_chan_scan_param_set); + sizeof(struct mwifiex_chan_scan_param_set); cmd_append_size += sizeof(chan_tlv->header) + - sizeof(struct mwifiex_chan_scan_param_set); + sizeof(struct mwifiex_chan_scan_param_set); } if (priv->sec_info.wpa_enabled) @@ -1112,9 +1112,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ADHOC, &pos); - cmd->size = cpu_to_le16((u16) - (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) - + S_DS_GEN + cmd_append_size)); + cmd->size = cpu_to_le16 + ((u16) (sizeof(struct host_cmd_ds_802_11_ad_hoc_join) + + S_DS_GEN + cmd_append_size)); adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap); @@ -1159,7 +1159,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) { dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* Update the created network descriptor with the new BSSID */ memcpy(bss_desc->mac_address, @@ -1172,7 +1172,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, * If BSSID has changed use SSID to compare instead of BSSID */ dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n", - bss_desc->ssid.ssid); + bss_desc->ssid.ssid); /* * Make a copy of current BSSID descriptor, only needed for @@ -1186,9 +1186,9 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, } dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n", - priv->adhoc_channel); + priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n", - priv->curr_bss_params.bss_descriptor.mac_address); + priv->curr_bss_params.bss_descriptor.mac_address); if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); @@ -1246,14 +1246,14 @@ int mwifiex_associate(struct mwifiex_private *priv, */ int mwifiex_adhoc_start(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *adhoc_ssid) + struct cfg80211_ssid *adhoc_ssid) { dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n", priv->adhoc_channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", - priv->curr_bss_params.bss_descriptor.channel); + priv->curr_bss_params.bss_descriptor.channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n", - priv->curr_bss_params.band); + priv->curr_bss_params.band); return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START, HostCmd_ACT_GEN_SET, 0, adhoc_ssid); @@ -1269,13 +1269,13 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc) { dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid); + priv->curr_bss_params.bss_descriptor.ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n", bss_desc->ssid.ssid); dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n", - bss_desc->ssid.ssid_len); + bss_desc->ssid.ssid_len); /* Check if the requested SSID is already joined */ if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len && @@ -1289,9 +1289,9 @@ int mwifiex_adhoc_join(struct mwifiex_private *priv, } dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n", - priv->curr_bss_params.bss_descriptor.channel); + priv->curr_bss_params.bss_descriptor.channel); dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n", - priv->curr_bss_params.band); + priv->curr_bss_params.band); return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN, HostCmd_ACT_GEN_SET, 0, bss_desc); diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index b728f54451e..9d1b3ca6334 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -64,11 +64,10 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, adapter->priv_num = 0; /* Allocate memory for private structure */ - adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), - GFP_KERNEL); + adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); if (!adapter->priv[0]) { - dev_err(adapter->dev, "%s: failed to alloc priv[0]\n", - __func__); + dev_err(adapter->dev, + "%s: failed to alloc priv[0]\n", __func__); goto error; } @@ -169,8 +168,8 @@ process_start: if ((adapter->ps_state == PS_STATE_SLEEP) && (adapter->pm_wakeup_card_req && !adapter->pm_wakeup_fw_try) && - (is_command_pending(adapter) - || !mwifiex_wmm_lists_empty(adapter))) { + (is_command_pending(adapter) || + !mwifiex_wmm_lists_empty(adapter))) { adapter->pm_wakeup_fw_try = true; adapter->if_ops.wakeup(adapter); continue; @@ -187,10 +186,10 @@ process_start: adapter->tx_lock_flag) break; - if (adapter->scan_processing || adapter->data_sent - || mwifiex_wmm_lists_empty(adapter)) { - if (adapter->cmd_sent || adapter->curr_cmd - || (!is_command_pending(adapter))) + if (adapter->scan_processing || adapter->data_sent || + mwifiex_wmm_lists_empty(adapter)) { + if (adapter->cmd_sent || adapter->curr_cmd || + (!is_command_pending(adapter))) break; } } @@ -223,10 +222,10 @@ process_start: /* * The ps_state may have been changed during processing of * Sleep Request event. */ - if ((adapter->ps_state == PS_STATE_SLEEP) - || (adapter->ps_state == PS_STATE_PRE_SLEEP) - || (adapter->ps_state == PS_STATE_SLEEP_CFM) - || adapter->tx_lock_flag) + if ((adapter->ps_state == PS_STATE_SLEEP) || + (adapter->ps_state == PS_STATE_PRE_SLEEP) || + (adapter->ps_state == PS_STATE_SLEEP_CFM) || + adapter->tx_lock_flag) continue; if (!adapter->cmd_sent && !adapter->curr_cmd) { @@ -249,8 +248,8 @@ process_start: } if (adapter->delay_null_pkt && !adapter->cmd_sent && - !adapter->curr_cmd && !is_command_pending(adapter) - && mwifiex_wmm_lists_empty(adapter)) { + !adapter->curr_cmd && !is_command_pending(adapter) && + mwifiex_wmm_lists_empty(adapter)) { if (!mwifiex_send_null_packet (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | @@ -371,7 +370,7 @@ mwifiex_fill_buffer(struct sk_buff *skb) iph = ip_hdr(skb); tid = IPTOS_PREC(iph->tos); pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", - eth->h_proto, tid, skb->priority); + eth->h_proto, tid, skb->priority); break; case __constant_htons(ETH_P_ARP): pr_debug("data: ARP packet: %04x\n", eth->h_proto); @@ -424,8 +423,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *new_skb; struct mwifiex_txinfo *tx_info; - dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n", - jiffies, priv->bss_index); + dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", + jiffies, priv->bss_type, priv->bss_num); if (priv->adapter->surprise_removed) { kfree_skb(skb); @@ -441,7 +440,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) { dev_dbg(priv->adapter->dev, "data: Tx: insufficient skb headroom %d\n", - skb_headroom(skb)); + skb_headroom(skb)); /* Insufficient skb headroom - allocate a new skb */ new_skb = skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN); @@ -454,14 +453,15 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) kfree_skb(skb); skb = new_skb; dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n", - skb_headroom(skb)); + skb_headroom(skb)); } tx_info = MWIFIEX_SKB_TXCB(skb); - tx_info->bss_index = priv->bss_index; + tx_info->bss_num = priv->bss_num; + tx_info->bss_type = priv->bss_type; mwifiex_fill_buffer(skb); - mwifiex_wmm_add_buf_txqueue(priv->adapter, skb); + mwifiex_wmm_add_buf_txqueue(priv, skb); atomic_inc(&priv->adapter->tx_pending); if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { @@ -493,8 +493,8 @@ mwifiex_set_mac_address(struct net_device *dev, void *addr) if (!ret) memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN); else - dev_err(priv->adapter->dev, "set mac address failed: ret=%d" - "\n", ret); + dev_err(priv->adapter->dev, + "set mac address failed: ret=%d\n", ret); memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); @@ -531,8 +531,8 @@ mwifiex_tx_timeout(struct net_device *dev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n", - jiffies, priv->bss_index); + dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", + jiffies, priv->bss_type, priv->bss_num); mwifiex_set_trans_start(dev); priv->num_tx_timeout++; } @@ -605,18 +605,6 @@ int is_command_pending(struct mwifiex_adapter *adapter) } /* - * This function returns the correct private structure pointer based - * upon the BSS number. - */ -struct mwifiex_private * -mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index) -{ - if (!adapter || (bss_index >= adapter->priv_num)) - return NULL; - return adapter->priv[bss_index]; -} - -/* * This is the main work queue function. * * It handles the main process, which in turn handles the complete @@ -715,7 +703,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, rtnl_lock(); /* Create station interface by default */ if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d", - NL80211_IFTYPE_STATION, NULL, NULL)) { + NL80211_IFTYPE_STATION, NULL, NULL)) { rtnl_unlock(); dev_err(adapter->dev, "cannot create default station" " interface\n"); @@ -792,7 +780,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) if (priv && priv->netdev) { if (!netif_queue_stopped(priv->netdev)) mwifiex_stop_net_dev_queue(priv->netdev, - adapter); + adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3186aa437f4..35225e9b108 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -217,8 +217,9 @@ struct mwifiex_802_11_security { u8 wpa2_enabled; u8 wapi_enabled; u8 wapi_key_on; - enum MWIFIEX_802_11_WEP_STATUS wep_status; + u8 wep_enabled; u32 authentication_mode; + u8 is_authtype_auto; u32 encryption_mode; }; @@ -243,7 +244,7 @@ struct ieee_types_generic { struct mwifiex_bssdescriptor { u8 mac_address[ETH_ALEN]; - struct mwifiex_802_11_ssid ssid; + struct cfg80211_ssid ssid; u32 privacy; s32 rssi; u32 channel; @@ -352,7 +353,6 @@ struct mwifiex_private; struct mwifiex_private { struct mwifiex_adapter *adapter; - u8 bss_index; u8 bss_type; u8 bss_role; u8 bss_priority; @@ -388,10 +388,11 @@ struct mwifiex_private { s16 bcn_rssi_avg; s16 bcn_nf_avg; struct mwifiex_bssdescriptor *attempted_bss_desc; - struct mwifiex_802_11_ssid prev_ssid; + struct cfg80211_ssid prev_ssid; u8 prev_bssid[ETH_ALEN]; struct mwifiex_current_bss_params curr_bss_params; u16 beacon_period; + u8 dtim_period; u16 listen_interval; u16 atim_window; u8 adhoc_channel; @@ -461,9 +462,9 @@ struct mwifiex_private { }; enum mwifiex_ba_status { - BA_STREAM_NOT_SETUP = 0, - BA_STREAM_SETUP_INPROGRESS, - BA_STREAM_SETUP_COMPLETE + BA_SETUP_NONE = 0, + BA_SETUP_INPROGRESS, + BA_SETUP_COMPLETE }; struct mwifiex_tx_ba_stream_tbl { @@ -746,8 +747,7 @@ void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node); int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); -s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, - struct mwifiex_802_11_ssid *ssid2); +s32 mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2); int mwifiex_associate(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv, @@ -759,25 +759,20 @@ void mwifiex_reset_connect_state(struct mwifiex_private *priv); u8 mwifiex_band_to_radio_type(u8 band); int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); int mwifiex_adhoc_start(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *adhoc_ssid); + struct cfg80211_ssid *adhoc_ssid); int mwifiex_adhoc_join(struct mwifiex_private *priv, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, - struct mwifiex_802_11_ssid *req_ssid); + struct cfg80211_ssid *req_ssid); int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, struct mwifiex_bssdescriptor *bss_desc); int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, struct host_cmd_ds_command *resp); int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd); -struct mwifiex_chan_freq_power * - mwifiex_get_cfp_by_band_and_channel_from_cfg80211( - struct mwifiex_private *priv, - u8 band, u16 channel); -struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211( - struct mwifiex_private *priv, - u8 band, u32 freq); +struct mwifiex_chan_freq_power *mwifiex_get_cfp(struct mwifiex_private *priv, + u8 band, u16 channel, u32 freq); u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, u8 ht_info); u32 mwifiex_find_freq_from_band_chan(u8, u8); @@ -846,8 +841,8 @@ mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter, for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { - if ((adapter->priv[i]->bss_num == bss_num) - && (adapter->priv[i]->bss_type == bss_type)) + if ((adapter->priv[i]->bss_num == bss_num) && + (adapter->priv[i]->bss_type == bss_type)) break; } } @@ -884,8 +879,6 @@ mwifiex_netdev_get_priv(struct net_device *dev) return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); } -struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter - *adapter, u8 bss_index); int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); @@ -899,7 +892,7 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, struct net_device *dev); int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, - struct mwifiex_802_11_ssid *req_ssid); + struct cfg80211_ssid *req_ssid); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); int mwifiex_disable_auto_ds(struct mwifiex_private *priv); @@ -908,13 +901,12 @@ int mwifiex_get_signal_info(struct mwifiex_private *priv, int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate); int mwifiex_request_scan(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *req_ssid); + struct cfg80211_ssid *req_ssid); int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, struct mwifiex_user_scan_cfg *scan_req); -int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel); int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); -int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel); +int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, int key_len, u8 key_index, int disable); diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 405350940a4..5867facd415 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -83,13 +83,11 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, struct pcie_service_card *card; pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", - pdev->vendor, pdev->device, pdev->revision); + pdev->vendor, pdev->device, pdev->revision); card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); - if (!card) { - pr_err("%s: failed to alloc memory\n", __func__); + if (!card) return -ENOMEM; - } card->dev = pdev; @@ -110,6 +108,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) { struct pcie_service_card *card; struct mwifiex_adapter *adapter; + struct mwifiex_private *priv; int i; card = pci_get_drvdata(pdev); @@ -128,16 +127,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == - MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) + MWIFIEX_BSS_ROLE_STA) && + adapter->priv[i]->media_connected) mwifiex_deauthenticate(adapter->priv[i], NULL); - mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY)); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + + mwifiex_disable_auto_ds(priv); - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); @@ -221,7 +219,7 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) netif_carrier_on(adapter->priv[i]->netdev); mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), - MWIFIEX_ASYNC_CMD); + MWIFIEX_ASYNC_CMD); return 0; } @@ -288,7 +286,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) while (mwifiex_pcie_ok_to_access_hw(adapter)) { i++; - udelay(10); + usleep_range(10, 20); /* 50ms max wait */ if (i == 50000) break; @@ -380,26 +378,26 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) /* allocate shared memory for the BD ring and divide the same in to several descriptors */ card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", - card->txbd_ring_size); + card->txbd_ring_size); card->txbd_ring_vbase = kzalloc(card->txbd_ring_size, GFP_KERNEL); if (!card->txbd_ring_vbase) { - dev_err(adapter->dev, "Unable to allocate buffer for txbd ring.\n"); + dev_err(adapter->dev, "Unable to alloc buffer for txbd ring\n"); return -ENOMEM; } card->txbd_ring_pbase = virt_to_phys(card->txbd_ring_vbase); - dev_dbg(adapter->dev, "info: txbd_ring - base: %p, pbase: %#x:%x," - "len: %x\n", card->txbd_ring_vbase, - (u32)card->txbd_ring_pbase, - (u32)((u64)card->txbd_ring_pbase >> 32), - card->txbd_ring_size); + dev_dbg(adapter->dev, + "info: txbd_ring - base: %p, pbase: %#x:%x, len: %x\n", + card->txbd_ring_vbase, (u32)card->txbd_ring_pbase, + (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->txbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->txbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate buffer here so that firmware can DMA data from it */ skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); @@ -412,10 +410,9 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: TX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)(((u64)*buf_pa >> 32)), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, + (u32)(((u64)*buf_pa >> 32)), skb->len); card->tx_buf_list[i] = skb; card->txbd_ring[i]->paddr = *buf_pa; @@ -469,9 +466,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + MWIFIEX_MAX_TXRX_BD; dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", - card->rxbd_ring_size); + card->rxbd_ring_size); card->rxbd_ring_vbase = kzalloc(card->rxbd_ring_size, GFP_KERNEL); if (!card->rxbd_ring_vbase) { dev_err(adapter->dev, "Unable to allocate buffer for " @@ -480,21 +477,23 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) } card->rxbd_ring_pbase = virt_to_phys(card->rxbd_ring_vbase); - dev_dbg(adapter->dev, "info: rxbd_ring - base: %p, pbase: %#x:%x," - "len: %#x\n", card->rxbd_ring_vbase, - (u32)card->rxbd_ring_pbase, - (u32)((u64)card->rxbd_ring_pbase >> 32), - card->rxbd_ring_size); + dev_dbg(adapter->dev, + "info: rxbd_ring - base: %p, pbase: %#x:%x, len: %#x\n", + card->rxbd_ring_vbase, (u32)card->rxbd_ring_pbase, + (u32)((u64)card->rxbd_ring_pbase >> 32), + card->rxbd_ring_size); for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->rxbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->rxbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate skb here so that firmware can DMA data from it */ skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for RX ring.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for RX ring.\n"); kfree(card->rxbd_ring_vbase); return -ENOMEM; } @@ -502,10 +501,9 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MWIFIEX_RX_DATA_BUF_SIZE); dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), + skb->len); card->rx_buf_list[i] = skb; card->rxbd_ring[i]->paddr = *buf_pa; @@ -562,32 +560,34 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_EVT_BD; + MWIFIEX_MAX_EVT_BD; dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", - card->evtbd_ring_size); + card->evtbd_ring_size); card->evtbd_ring_vbase = kzalloc(card->evtbd_ring_size, GFP_KERNEL); if (!card->evtbd_ring_vbase) { - dev_err(adapter->dev, "Unable to allocate buffer. " - "Terminating download\n"); + dev_err(adapter->dev, + "Unable to allocate buffer. Terminating download\n"); return -ENOMEM; } card->evtbd_ring_pbase = virt_to_phys(card->evtbd_ring_vbase); - dev_dbg(adapter->dev, "info: CMDRSP/EVT bd_ring - base: %p, " - "pbase: %#x:%x, len: %#x\n", card->evtbd_ring_vbase, - (u32)card->evtbd_ring_pbase, - (u32)((u64)card->evtbd_ring_pbase >> 32), - card->evtbd_ring_size); + dev_dbg(adapter->dev, + "info: CMDRSP/EVT bd_ring - base: %p pbase: %#x:%x len: %#x\n", + card->evtbd_ring_vbase, (u32)card->evtbd_ring_pbase, + (u32)((u64)card->evtbd_ring_pbase >> 32), + card->evtbd_ring_size); for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->evtbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) * i)); + (card->evtbd_ring_vbase + + (sizeof(struct mwifiex_pcie_buf_desc) + * i)); /* Allocate skb here so that firmware can DMA data from it */ skb = dev_alloc_skb(MAX_EVENT_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for EVENT buf.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for EVENT buf.\n"); kfree(card->evtbd_ring_vbase); return -ENOMEM; } @@ -595,10 +595,9 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) skb_put(skb, MAX_EVENT_SIZE); dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, " - "buf_len: %#x\n", skb, skb->data, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), - skb->len); + "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", + skb, skb->data, (u32)*buf_pa, (u32)((u64)*buf_pa >> 32), + skb->len); card->evt_buf_list[i] = skb; card->evtbd_ring[i]->paddr = *buf_pa; @@ -647,8 +646,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) /* Allocate memory for receiving command response data */ skb = dev_alloc_skb(MWIFIEX_UPLD_SIZE); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for command " - "response data.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for command response data.\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -659,8 +658,8 @@ static int mwifiex_pcie_alloc_cmdrsp_buf(struct mwifiex_adapter *adapter) /* Allocate memory for sending command to firmware */ skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for command " - "data.\n"); + dev_err(adapter->dev, + "Unable to allocate skb for command data.\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -702,8 +701,8 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) /* Allocate memory for sleep cookie */ skb = dev_alloc_skb(sizeof(u32)); if (!skb) { - dev_err(adapter->dev, "Unable to allocate skb for sleep " - "cookie!\n"); + dev_err(adapter->dev, + "Unable to allocate skb for sleep cookie!\n"); return -ENOMEM; } mwifiex_update_sk_buff_pa(skb); @@ -713,7 +712,7 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) *(u32 *)skb->data = FW_AWAKE_COOKIE; dev_dbg(adapter->dev, "alloc_scook: sleep cookie=0x%x\n", - *((u32 *)skb->data)); + *((u32 *)skb->data)); /* Save the sleep cookie */ card->sleep_cookie = skb; @@ -757,15 +756,15 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Read the TX ring read pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { - dev_err(adapter->dev, "SEND DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "SEND DATA: failed to read REG_TXBD_RDPTR\n"); return -1; } wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; dev_dbg(adapter->dev, "info: SEND DATA: <Rd: %#x, Wr: %#x>\n", rdptr, - card->txbd_wrptr); + card->txbd_wrptr); if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != (rdptr & MWIFIEX_TXBD_MASK)) || ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != @@ -797,32 +796,31 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, - card->txbd_wrptr)) { - dev_err(adapter->dev, "SEND DATA: failed to write " - "REG_TXBD_WRPTR\n"); + card->txbd_wrptr)) { + dev_err(adapter->dev, + "SEND DATA: failed to write REG_TXBD_WRPTR\n"); return 0; } /* Send the TX ready interrupt */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DNLD_RDY)) { - dev_err(adapter->dev, "SEND DATA: failed to assert " - "door-bell interrupt.\n"); + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); return -1; } dev_dbg(adapter->dev, "info: SEND DATA: Updated <Rd: %#x, Wr: " - "%#x> and sent packet to firmware " - "successfully\n", rdptr, - card->txbd_wrptr); + "%#x> and sent packet to firmware successfully\n", + rdptr, card->txbd_wrptr); } else { - dev_dbg(adapter->dev, "info: TX Ring full, can't send anymore " - "packets to firmware\n"); + dev_dbg(adapter->dev, + "info: TX Ring full, can't send packets to fw\n"); adapter->data_sent = true; /* Send the TX ready interrupt */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DNLD_RDY)) - dev_err(adapter->dev, "SEND DATA: failed to assert " - "door-bell interrupt\n"); + dev_err(adapter->dev, + "SEND DATA: failed to assert door-bell intr\n"); return -EBUSY; } @@ -842,8 +840,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "RECV DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to read REG_TXBD_RDPTR\n"); ret = -1; goto done; } @@ -861,12 +859,13 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) /* Get data length from interface header - first byte is len, second byte is type */ rx_len = *((u16 *)skb_data->data); - dev_dbg(adapter->dev, "info: RECV DATA: Rd=%#x, Wr=%#x, " - "Len=%d\n", card->rxbd_rdptr, wrptr, rx_len); + dev_dbg(adapter->dev, + "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", + card->rxbd_rdptr, wrptr, rx_len); skb_tmp = dev_alloc_skb(rx_len); if (!skb_tmp) { - dev_dbg(adapter->dev, "info: Failed to alloc skb " - "for RX\n"); + dev_dbg(adapter->dev, + "info: Failed to alloc skb for RX\n"); ret = -EBUSY; goto done; } @@ -881,26 +880,26 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) MWIFIEX_BD_FLAG_ROLLOVER_IND); } dev_dbg(adapter->dev, "info: RECV DATA: <Rd: %#x, Wr: %#x>\n", - card->rxbd_rdptr, wrptr); + card->rxbd_rdptr, wrptr); /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr)) { - dev_err(adapter->dev, "RECV DATA: failed to " - "write REG_RXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to write REG_RXBD_RDPTR\n"); ret = -1; goto done; } /* Read the RX ring Write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "RECV DATA: failed to read " - "REG_TXBD_RDPTR\n"); + dev_err(adapter->dev, + "RECV DATA: failed to read REG_TXBD_RDPTR\n"); ret = -1; goto done; } - dev_dbg(adapter->dev, "info: RECV DATA: Received packet from " - "firmware successfully\n"); + dev_dbg(adapter->dev, + "info: RECV DATA: Rcvd packet from fw successfully\n"); mwifiex_handle_rx_packet(adapter, skb_tmp); } @@ -919,17 +918,19 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) phys_addr_t *buf_pa = MWIFIEX_SKB_PACB(skb); if (!(skb->data && skb->len && *buf_pa)) { - dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x:%x, " - "%x>\n", __func__, skb->data, skb->len, - (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); + dev_err(adapter->dev, + "Invalid parameter in %s <%p, %#x:%x, %x>\n", + __func__, skb->data, skb->len, + (u32)*buf_pa, (u32)((u64)*buf_pa >> 32)); return -1; } /* Write the lower 32bits of the physical address to scratch * register 0 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)*buf_pa)) { - dev_err(adapter->dev, "%s: failed to write download command " - "to boot code.\n", __func__); + dev_err(adapter->dev, + "%s: failed to write download command to boot code.\n", + __func__); return -1; } @@ -937,23 +938,25 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) * register 1 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, (u32)((u64)*buf_pa >> 32))) { - dev_err(adapter->dev, "%s: failed to write download command " - "to boot code.\n", __func__); + dev_err(adapter->dev, + "%s: failed to write download command to boot code.\n", + __func__); return -1; } /* Write the command length to scratch register 2 */ if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { - dev_err(adapter->dev, "%s: failed to write command length to " - "scratch register 2\n", __func__); + dev_err(adapter->dev, + "%s: failed to write command len to scratch reg 2\n", + __func__); return -1; } /* Ring the door bell */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DOOR_BELL)) { - dev_err(adapter->dev, "%s: failed to assert door-bell " - "interrupt.\n", __func__); + dev_err(adapter->dev, + "%s: failed to assert door-bell intr\n", __func__); return -1; } @@ -973,14 +976,14 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) if (!(skb->data && skb->len)) { dev_err(adapter->dev, "Invalid parameter in %s <%p, %#x>\n", - __func__, skb->data, skb->len); + __func__, skb->data, skb->len); return -1; } /* Make sure a command response buffer is available */ if (!card->cmdrsp_buf) { - dev_err(adapter->dev, "No response buffer available, send " - "command failed\n"); + dev_err(adapter->dev, + "No response buffer available, send command failed\n"); return -EBUSY; } @@ -1011,17 +1014,18 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Write the lower 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, - (u32)*cmdrsp_buf_pa)) { - dev_err(adapter->dev, "Failed to write download command to boot code.\n"); + (u32)*cmdrsp_buf_pa)) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, - (u32)((u64)*cmdrsp_buf_pa >> 32))) { - dev_err(adapter->dev, "Failed to write download command" - " to boot code.\n"); + (u32)((u64)*cmdrsp_buf_pa >> 32))) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } @@ -1029,27 +1033,25 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) cmd_buf_pa = MWIFIEX_SKB_PACB(card->cmd_buf); /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ - if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, - (u32)*cmd_buf_pa)) { - dev_err(adapter->dev, "Failed to write download command " - "to boot code.\n"); + if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)*cmd_buf_pa)) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, - (u32)((u64)*cmd_buf_pa >> 32))) { - dev_err(adapter->dev, "Failed to write download command " - "to boot code.\n"); + (u32)((u64)*cmd_buf_pa >> 32))) { + dev_err(adapter->dev, + "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } /* Write the command length to REG_CMD_SIZE */ - if (mwifiex_write_reg(adapter, REG_CMD_SIZE, - card->cmd_buf->len)) { - dev_err(adapter->dev, "Failed to write command length to " - "REG_CMD_SIZE\n"); + if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) { + dev_err(adapter->dev, + "Failed to write cmd len to REG_CMD_SIZE\n"); ret = -1; goto done; } @@ -1057,8 +1059,8 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* Ring the door bell */ if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_DOOR_BELL)) { - dev_err(adapter->dev, "Failed to assert door-bell " - "interrupt.\n"); + dev_err(adapter->dev, + "Failed to assert door-bell intr\n"); ret = -1; goto done; } @@ -1076,30 +1078,29 @@ done: static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + struct sk_buff *skb = card->cmdrsp_buf; int count = 0; dev_dbg(adapter->dev, "info: Rx CMD Response\n"); if (!adapter->curr_cmd) { - skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); + skb_pull(skb, INTF_HEADER_LEN); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { - mwifiex_process_sleep_confirm_resp(adapter, - card->cmdrsp_buf->data, - card->cmdrsp_buf->len); + mwifiex_process_sleep_confirm_resp(adapter, skb->data, + skb->len); while (mwifiex_pcie_ok_to_access_hw(adapter) && (count++ < 10)) - udelay(50); + usleep_range(50, 60); } else { - dev_err(adapter->dev, "There is no command but " - "got cmdrsp\n"); + dev_err(adapter->dev, + "There is no command but got cmdrsp\n"); } - memcpy(adapter->upld_buf, card->cmdrsp_buf->data, - min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, - card->cmdrsp_buf->len)); - skb_push(card->cmdrsp_buf, INTF_HEADER_LEN); + memcpy(adapter->upld_buf, skb->data, + min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + skb_push(skb, INTF_HEADER_LEN); } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { - skb_pull(card->cmdrsp_buf, INTF_HEADER_LEN); - adapter->curr_cmd->resp_skb = card->cmdrsp_buf; + skb_pull(skb, INTF_HEADER_LEN); + adapter->curr_cmd->resp_skb = skb; adapter->cmd_resp_received = true; /* Take the pointer and set it to CMD node and will return in the response complete callback */ @@ -1109,15 +1110,15 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) will prevent firmware from writing to the same response buffer again. */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { - dev_err(adapter->dev, "cmd_done: failed to clear " - "cmd_rsp address.\n"); + dev_err(adapter->dev, + "cmd_done: failed to clear cmd_rsp_addr_lo\n"); return -1; } /* Write the upper 32bits of the cmdrsp buffer physical address */ if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { - dev_err(adapter->dev, "cmd_done: failed to clear " - "cmd_rsp address.\n"); + dev_err(adapter->dev, + "cmd_done: failed to clear cmd_rsp_addr_hi\n"); return -1; } } @@ -1151,8 +1152,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) u32 wrptr, event; if (adapter->event_received) { - dev_dbg(adapter->dev, "info: Event being processed, "\ - "do not process this interrupt just yet\n"); + dev_dbg(adapter->dev, "info: Event being processed, " + "do not process this interrupt just yet\n"); return 0; } @@ -1163,14 +1164,15 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) /* Read the event ring write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "EventReady: failed to read REG_EVTBD_WRPTR\n"); + dev_err(adapter->dev, + "EventReady: failed to read REG_EVTBD_WRPTR\n"); return -1; } dev_dbg(adapter->dev, "info: EventReady: Initial <Rd: 0x%x, Wr: 0x%x>", - card->evtbd_rdptr, wrptr); - if (((wrptr & MWIFIEX_EVTBD_MASK) != - (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) || + card->evtbd_rdptr, wrptr); + if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr + & MWIFIEX_EVTBD_MASK)) || ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { struct sk_buff *skb_cmd; @@ -1230,13 +1232,14 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, if (rdptr >= MWIFIEX_MAX_EVT_BD) { dev_err(adapter->dev, "event_complete: Invalid rdptr 0x%x\n", - rdptr); + rdptr); return -EINVAL; } /* Read the event ring write pointer set by firmware */ if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { - dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_WRPTR\n"); + dev_err(adapter->dev, + "event_complete: failed to read REG_EVTBD_WRPTR\n"); return -1; } @@ -1249,9 +1252,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, card->evtbd_ring[rdptr]->flags = 0; skb = NULL; } else { - dev_dbg(adapter->dev, "info: ERROR: Buffer is still valid at " - "index %d, <%p, %p>\n", rdptr, - card->evt_buf_list[rdptr], skb); + dev_dbg(adapter->dev, + "info: ERROR: buf still valid at index %d, <%p, %p>\n", + rdptr, card->evt_buf_list[rdptr], skb); } if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { @@ -1261,11 +1264,12 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, } dev_dbg(adapter->dev, "info: Updated <Rd: 0x%x, Wr: 0x%x>", - card->evtbd_rdptr, wrptr); + card->evtbd_rdptr, wrptr); /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { - dev_err(adapter->dev, "event_complete: failed to read REG_EVTBD_RDPTR\n"); + dev_err(adapter->dev, + "event_complete: failed to read REG_EVTBD_RDPTR\n"); return -1; } @@ -1299,17 +1303,17 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } if (!firmware || !firmware_len) { - dev_err(adapter->dev, "No firmware image found! " - "Terminating download\n"); + dev_err(adapter->dev, + "No firmware image found! Terminating download\n"); return -1; } dev_dbg(adapter->dev, "info: Downloading FW image (%d bytes)\n", - firmware_len); + firmware_len); if (mwifiex_pcie_disable_host_int(adapter)) { - dev_err(adapter->dev, "%s: Disabling interrupts" - " failed.\n", __func__); + dev_err(adapter->dev, + "%s: Disabling interrupts failed.\n", __func__); return -1; } @@ -1332,19 +1336,20 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, &len); if (ret) { - dev_warn(adapter->dev, "Failed reading length from boot code\n"); + dev_warn(adapter->dev, + "Failed reading len from boot code\n"); goto done; } if (len) break; - udelay(10); + usleep_range(10, 20); } if (!len) { break; } else if (len > MWIFIEX_UPLD_SIZE) { pr_err("FW download failure @ %d, invalid length %d\n", - offset, len); + offset, len); ret = -1; goto done; } @@ -1360,8 +1365,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, goto done; } dev_err(adapter->dev, "FW CRC error indicated by the " - "helper: len = 0x%04X, txlen = " - "%d\n", len, txlen); + "helper: len = 0x%04X, txlen = %d\n", + len, txlen); len &= ~BIT(0); /* Setting this to 0 to resend from same offset */ txlen = 0; @@ -1374,9 +1379,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "."); - tx_blocks = - (txlen + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / - MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; + tx_blocks = (txlen + + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / + MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; /* Copy payload to buffer */ memmove(skb->data, &firmware[offset], txlen); @@ -1387,7 +1392,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, /* Send the boot command to device */ if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { - dev_err(adapter->dev, "Failed to send firmware download command\n"); + dev_err(adapter->dev, + "Failed to send firmware download command\n"); ret = -1; goto done; } @@ -1396,8 +1402,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS, &ireg_intr)) { dev_err(adapter->dev, "%s: Failed to read " - "interrupt status during " - "fw dnld.\n", __func__); + "interrupt status during fw dnld.\n", + __func__); ret = -1; goto done; } @@ -1407,7 +1413,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } while (true); dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", - offset); + offset); ret = 0; @@ -1430,14 +1436,15 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) /* Mask spurios interrupts */ if (mwifiex_write_reg(adapter, PCIE_HOST_INT_STATUS_MASK, - HOST_INTR_MASK)) { + HOST_INTR_MASK)) { dev_warn(adapter->dev, "Write register failed\n"); return -1; } dev_dbg(adapter->dev, "Setting driver ready signature\n"); if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { - dev_err(adapter->dev, "Failed to write driver ready signature\n"); + dev_err(adapter->dev, + "Failed to write driver ready signature\n"); return -1; } @@ -1468,8 +1475,9 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) adapter->winner = 1; ret = -1; } else { - dev_err(adapter->dev, "PCI-E is not the winner <%#x, %d>, exit download\n", - ret, adapter->winner); + dev_err(adapter->dev, + "PCI-E is not the winner <%#x,%d>, exit dnld\n", + ret, adapter->winner); ret = 0; } } @@ -1512,10 +1520,11 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) (adapter->ps_state == PS_STATE_SLEEP)) { mwifiex_pcie_enable_host_int(adapter); if (mwifiex_write_reg(adapter, - PCIE_CPU_INT_EVENT, - CPU_INTR_SLEEP_CFM_DONE)) { - dev_warn(adapter->dev, "Write register" - " failed\n"); + PCIE_CPU_INT_EVENT, + CPU_INTR_SLEEP_CFM_DONE) + ) { + dev_warn(adapter->dev, + "Write register failed\n"); return; } @@ -1551,7 +1560,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) card = (struct pcie_service_card *) pci_get_drvdata(pdev); if (!card || !card->adapter) { pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, - card ? card->adapter : NULL); + card ? card->adapter : NULL); goto exit; } adapter = card->adapter; @@ -1594,7 +1603,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (adapter->int_status & HOST_INTR_DNLD_DONE) { adapter->int_status &= ~HOST_INTR_DNLD_DONE; if (adapter->data_sent) { - dev_dbg(adapter->dev, "info: DATA sent Interrupt\n"); + dev_dbg(adapter->dev, "info: DATA sent intr\n"); adapter->data_sent = false; } } @@ -1616,7 +1625,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (adapter->int_status & HOST_INTR_CMD_DONE) { adapter->int_status &= ~HOST_INTR_CMD_DONE; if (adapter->cmd_sent) { - dev_dbg(adapter->dev, "info: CMD sent Interrupt\n"); + dev_dbg(adapter->dev, + "info: CMD sent Interrupt\n"); adapter->cmd_sent = false; } /* Handle command response */ @@ -1628,15 +1638,17 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (mwifiex_pcie_ok_to_access_hw(adapter)) { if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, &pcie_ireg)) { - dev_warn(adapter->dev, "Read register failed\n"); + dev_warn(adapter->dev, + "Read register failed\n"); return -1; } if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { if (mwifiex_write_reg(adapter, - PCIE_HOST_INT_STATUS, ~pcie_ireg)) { - dev_warn(adapter->dev, "Write register" - " failed\n"); + PCIE_HOST_INT_STATUS, + ~pcie_ireg)) { + dev_warn(adapter->dev, + "Write register failed\n"); return -1; } adapter->int_status |= pcie_ireg; @@ -1646,7 +1658,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) } } dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", - adapter->cmd_sent, adapter->data_sent); + adapter->cmd_sent, adapter->data_sent); mwifiex_pcie_enable_host_int(adapter); return 0; @@ -1737,8 +1749,9 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) goto err_iomap2; } - dev_dbg(adapter->dev, "PCI memory map Virt0: %p PCI memory map Virt2: " - "%p\n", card->pci_mmap, card->pci_mmap1); + dev_dbg(adapter->dev, + "PCI memory map Virt0: %p PCI memory map Virt2: %p\n", + card->pci_mmap, card->pci_mmap1); card->cmdrsp_buf = NULL; ret = mwifiex_pcie_create_txbd_ring(adapter); @@ -1808,7 +1821,8 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "Clearing driver ready signature\n"); if (user_rmmod) { if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) - dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); + dev_err(adapter->dev, + "Failed to write driver not-ready signature\n"); } if (pdev) { diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6396d3318ea..aff9cd763f2 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -125,7 +125,7 @@ mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) ieee_hdr.element_id == WLAN_EID_RSN))) { iebody = (struct ie_body *) (((u8 *) bss_desc->bcn_rsn_ie->data) + - RSN_GTK_OUI_OFFSET); + RSN_GTK_OUI_OFFSET); oui = &mwifiex_rsn_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); if (ret) @@ -148,8 +148,9 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) struct ie_body *iebody; u8 ret = MWIFIEX_OUI_NOT_PRESENT; - if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)). - vend_hdr.element_id == WLAN_EID_WPA))) { + if (((bss_desc->bcn_wpa_ie) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == + WLAN_EID_WPA))) { iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; oui = &mwifiex_wpa_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); @@ -163,8 +164,7 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) * This function compares two SSIDs and checks if they match. */ s32 -mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, - struct mwifiex_802_11_ssid *ssid2) +mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) { if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) return -1; @@ -176,8 +176,8 @@ mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wapi(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { if (priv->sec_info.wapi_enabled && (bss_desc->bcn_wapi_ie && @@ -193,19 +193,17 @@ mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv, * scanned network is compatible with it. */ static bool -mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_no_sec(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED - && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled - && ((!bss_desc->bcn_wpa_ie) || + if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && + !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != - WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || + WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != - WLAN_EID_RSN)) - && !priv->sec_info.encryption_mode - && !bss_desc->privacy) { + WLAN_EID_RSN)) && + !priv->sec_info.encryption_mode && !bss_desc->privacy) { return true; } return false; @@ -216,12 +214,11 @@ mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv, * is compatible with it. */ static bool -mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_static_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED - && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled - && bss_desc->privacy) { + if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && + !priv->sec_info.wpa2_enabled && bss_desc->privacy) { return true; } return false; @@ -232,13 +229,12 @@ mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wpa(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED - && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled - && ((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr. - element_id == WLAN_EID_WPA)) + if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled && + !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) && + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id == WLAN_EID_WPA)) /* * Privacy bit may NOT be set in some APs like * LinkSys WRT54G && bss_desc->privacy @@ -253,8 +249,7 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, (bss_desc->bcn_rsn_ie) ? (*(bss_desc->bcn_rsn_ie)). ieee_hdr.element_id : 0, - (priv->sec_info.wep_status == - MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d", + (priv->sec_info.wep_enabled) ? "e" : "d", (priv->sec_info.wpa_enabled) ? "e" : "d", (priv->sec_info.wpa2_enabled) ? "e" : "d", priv->sec_info.encryption_mode, @@ -269,18 +264,18 @@ mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_wpa2(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED - && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled - && ((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id == WLAN_EID_RSN)) - /* - * Privacy bit may NOT be set in some APs like - * LinkSys WRT54G && bss_desc->privacy - */ - ) { + if (!priv->sec_info.wep_enabled && + !priv->sec_info.wpa_enabled && + priv->sec_info.wpa2_enabled && + ((bss_desc->bcn_rsn_ie) && + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) { + /* + * Privacy bit may NOT be set in some APs like + * LinkSys WRT54G && bss_desc->privacy + */ dev_dbg(priv->adapter->dev, "info: %s: WPA2: " " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s " "EncMode=%#x privacy=%#x\n", __func__, @@ -290,8 +285,7 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, (bss_desc->bcn_rsn_ie) ? (*(bss_desc->bcn_rsn_ie)). ieee_hdr.element_id : 0, - (priv->sec_info.wep_status == - MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d", + (priv->sec_info.wep_enabled) ? "e" : "d", (priv->sec_info.wpa_enabled) ? "e" : "d", (priv->sec_info.wpa2_enabled) ? "e" : "d", priv->sec_info.encryption_mode, @@ -306,17 +300,16 @@ mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv, * compatible with it. */ static bool -mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED - && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled - && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr. - element_id != WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id != WLAN_EID_RSN)) - && !priv->sec_info.encryption_mode - && bss_desc->privacy) { + if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && + !priv->sec_info.wpa2_enabled && + ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && + !priv->sec_info.encryption_mode && bss_desc->privacy) { return true; } return false; @@ -327,17 +320,16 @@ mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv, * is compatible with it. */ static bool -mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv, - struct mwifiex_bssdescriptor *bss_desc) +mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv, + struct mwifiex_bssdescriptor *bss_desc) { - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED - && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled - && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr. - element_id != WLAN_EID_WPA)) - && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id != WLAN_EID_RSN)) - && priv->sec_info.encryption_mode - && bss_desc->privacy) { + if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled && + !priv->sec_info.wpa2_enabled && + ((!bss_desc->bcn_wpa_ie) || + ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id != WLAN_EID_WPA)) && + ((!bss_desc->bcn_rsn_ie) || + ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) && + priv->sec_info.encryption_mode && bss_desc->privacy) { dev_dbg(priv->adapter->dev, "info: %s: dynamic " "WEP: wpa_ie=%#x wpa2_ie=%#x " "EncMode=%#x privacy=%#x\n", @@ -382,8 +374,9 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, bss_desc->disable_11n = false; /* Don't check for compatibility if roaming */ - if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION) - && (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) + if (priv->media_connected && + (priv->bss_mode == NL80211_IFTYPE_STATION) && + (bss_desc->bss_mode == NL80211_IFTYPE_STATION)) return 0; if (priv->wps.session_enable) { @@ -392,32 +385,30 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, return 0; } - if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) { + if (mwifiex_is_bss_wapi(priv, bss_desc)) { dev_dbg(adapter->dev, "info: return success for WAPI AP\n"); return 0; } if (bss_desc->bss_mode == mode) { - if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) { + if (mwifiex_is_bss_no_sec(priv, bss_desc)) { /* No security */ return 0; - } else if (mwifiex_is_network_compatible_for_static_wep(priv, - bss_desc)) { + } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) { /* Static WEP enabled */ dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n"); bss_desc->disable_11n = true; return 0; - } else if (mwifiex_is_network_compatible_for_wpa(priv, - bss_desc)) { + } else if (mwifiex_is_bss_wpa(priv, bss_desc)) { /* WPA enabled */ - if (((priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && bss_desc->bcn_ht_cap) - && !mwifiex_is_wpa_oui_present(bss_desc, - CIPHER_SUITE_CCMP)) { - - if (mwifiex_is_wpa_oui_present(bss_desc, - CIPHER_SUITE_TKIP)) { + if (((priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + bss_desc->bcn_ht_cap) && + !mwifiex_is_wpa_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_wpa_oui_present + (bss_desc, CIPHER_SUITE_TKIP)) { dev_dbg(adapter->dev, "info: Disable 11n if AES " "is not supported by AP\n"); @@ -427,17 +418,16 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, } } return 0; - } else if (mwifiex_is_network_compatible_for_wpa2(priv, - bss_desc)) { + } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) { /* WPA2 enabled */ - if (((priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN) - && bss_desc->bcn_ht_cap) - && !mwifiex_is_rsn_oui_present(bss_desc, - CIPHER_SUITE_CCMP)) { - - if (mwifiex_is_rsn_oui_present(bss_desc, - CIPHER_SUITE_TKIP)) { + if (((priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN) && + bss_desc->bcn_ht_cap) && + !mwifiex_is_rsn_oui_present(bss_desc, + CIPHER_SUITE_CCMP)) { + + if (mwifiex_is_rsn_oui_present + (bss_desc, CIPHER_SUITE_TKIP)) { dev_dbg(adapter->dev, "info: Disable 11n if AES " "is not supported by AP\n"); @@ -447,32 +437,26 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, } } return 0; - } else if (mwifiex_is_network_compatible_for_adhoc_aes(priv, - bss_desc)) { + } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) { /* Ad-hoc AES enabled */ return 0; - } else if (mwifiex_is_network_compatible_for_dynamic_wep(priv, - bss_desc)) { + } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) { /* Dynamic WEP enabled */ return 0; } /* Security doesn't match */ - dev_dbg(adapter->dev, "info: %s: failed: " - "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode" - "=%#x privacy=%#x\n", - __func__, - (bss_desc->bcn_wpa_ie) ? - (*(bss_desc->bcn_wpa_ie)).vend_hdr. - element_id : 0, - (bss_desc->bcn_rsn_ie) ? - (*(bss_desc->bcn_rsn_ie)).ieee_hdr. - element_id : 0, - (priv->sec_info.wep_status == - MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d", - (priv->sec_info.wpa_enabled) ? "e" : "d", - (priv->sec_info.wpa2_enabled) ? "e" : "d", - priv->sec_info.encryption_mode, bss_desc->privacy); + dev_dbg(adapter->dev, + "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s " + "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__, + (bss_desc->bcn_wpa_ie) ? + (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0, + (bss_desc->bcn_rsn_ie) ? + (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0, + (priv->sec_info.wep_enabled) ? "e" : "d", + (priv->sec_info.wpa_enabled) ? "e" : "d", + (priv->sec_info.wpa2_enabled) ? "e" : "d", + priv->sec_info.encryption_mode, bss_desc->privacy); return -1; } @@ -489,11 +473,11 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, */ static void mwifiex_scan_create_channel_list(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg - *user_scan_in, - struct mwifiex_chan_scan_param_set - *scan_chan_list, - u8 filtered_scan) + const struct mwifiex_user_scan_cfg + *user_scan_in, + struct mwifiex_chan_scan_param_set + *scan_chan_list, + u8 filtered_scan) { enum ieee80211_band band; struct ieee80211_supported_band *sband; @@ -515,7 +499,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, scan_chan_list[chan_idx].radio_type = band; if (user_scan_in && - user_scan_in->chan_list[0].scan_time) + user_scan_in->chan_list[0].scan_time) scan_chan_list[chan_idx].max_scan_time = cpu_to_le16((u16) user_scan_in-> chan_list[0].scan_time); @@ -604,19 +588,19 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, * - done_early is set (controlling individual scanning of * 1,6,11) */ - while (tlv_idx < max_chan_per_scan - && tmp_chan_list->chan_number && !done_early) { + while (tlv_idx < max_chan_per_scan && + tmp_chan_list->chan_number && !done_early) { dev_dbg(priv->adapter->dev, "info: Scan: Chan(%3d), Radio(%d)," " Mode(%d, %d), Dur(%d)\n", - tmp_chan_list->chan_number, - tmp_chan_list->radio_type, - tmp_chan_list->chan_scan_mode_bitmap - & MWIFIEX_PASSIVE_SCAN, - (tmp_chan_list->chan_scan_mode_bitmap - & MWIFIEX_DISABLE_CHAN_FILT) >> 1, - le16_to_cpu(tmp_chan_list->max_scan_time)); + tmp_chan_list->chan_number, + tmp_chan_list->radio_type, + tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_PASSIVE_SCAN, + (tmp_chan_list->chan_scan_mode_bitmap + & MWIFIEX_DISABLE_CHAN_FILT) >> 1, + le16_to_cpu(tmp_chan_list->max_scan_time)); /* Copy the current channel TLV to the command being prepared */ @@ -658,9 +642,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Stop the loop if the *current* channel is in the 1,6,11 set and we are not filtering on a BSSID or SSID. */ - if (!filtered_scan && (tmp_chan_list->chan_number == 1 - || tmp_chan_list->chan_number == 6 - || tmp_chan_list->chan_number == 11)) + if (!filtered_scan && + (tmp_chan_list->chan_number == 1 || + tmp_chan_list->chan_number == 6 || + tmp_chan_list->chan_number == 11)) done_early = true; /* Increment the tmp pointer to the next channel to @@ -670,9 +655,10 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Stop the loop if the *next* channel is in the 1,6,11 set. This will cause it to be the only channel scanned on the next interation */ - if (!filtered_scan && (tmp_chan_list->chan_number == 1 - || tmp_chan_list->chan_number == 6 - || tmp_chan_list->chan_number == 11)) + if (!filtered_scan && + (tmp_chan_list->chan_number == 1 || + tmp_chan_list->chan_number == 6 || + tmp_chan_list->chan_number == 11)) done_early = true; } @@ -724,15 +710,13 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, * If the number of probes is not set, adapter default setting is used. */ static void -mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in, - struct mwifiex_scan_cmd_config *scan_cfg_out, - struct mwifiex_ie_types_chan_list_param_set - **chan_list_out, - struct mwifiex_chan_scan_param_set - *scan_chan_list, - u8 *max_chan_per_scan, u8 *filtered_scan, - u8 *scan_current_only) +mwifiex_config_scan(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in, + struct mwifiex_scan_cmd_config *scan_cfg_out, + struct mwifiex_ie_types_chan_list_param_set **chan_list_out, + struct mwifiex_chan_scan_param_set *scan_chan_list, + u8 *max_chan_per_scan, u8 *filtered_scan, + u8 *scan_current_only) { struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_ie_types_num_probes *num_probes_tlv; @@ -747,7 +731,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, u16 scan_dur; u8 channel; u8 radio_type; - u32 ssid_idx; + int i; u8 ssid_filter; u8 rates[MWIFIEX_SUPPORTED_RATES]; u32 rates_size; @@ -802,14 +786,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, user_scan_in->specific_bssid, sizeof(scan_cfg_out->specific_bssid)); - for (ssid_idx = 0; - ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list)) - && (*user_scan_in->ssid_list[ssid_idx].ssid - || user_scan_in->ssid_list[ssid_idx].max_len)); - ssid_idx++) { - - ssid_len = strlen(user_scan_in->ssid_list[ssid_idx]. - ssid) + 1; + for (i = 0; i < user_scan_in->num_ssids; i++) { + ssid_len = user_scan_in->ssid_list[i].ssid_len; wildcard_ssid_tlv = (struct mwifiex_ie_types_wildcard_ssid_params *) @@ -820,19 +798,26 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, (u16) (ssid_len + sizeof(wildcard_ssid_tlv-> max_ssid_length))); - /* max_ssid_length = 0 tells firmware to perform - specific scan for the SSID filled */ - wildcard_ssid_tlv->max_ssid_length = 0; + /* + * max_ssid_length = 0 tells firmware to perform + * specific scan for the SSID filled, whereas + * max_ssid_length = IEEE80211_MAX_SSID_LEN is for + * wildcard scan. + */ + if (ssid_len) + wildcard_ssid_tlv->max_ssid_length = 0; + else + wildcard_ssid_tlv->max_ssid_length = + IEEE80211_MAX_SSID_LEN; memcpy(wildcard_ssid_tlv->ssid, - user_scan_in->ssid_list[ssid_idx].ssid, - ssid_len); + user_scan_in->ssid_list[i].ssid, ssid_len); tlv_pos += (sizeof(wildcard_ssid_tlv->header) + le16_to_cpu(wildcard_ssid_tlv->header.len)); - dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n", - ssid_idx, wildcard_ssid_tlv->ssid, + dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n", + i, wildcard_ssid_tlv->ssid, wildcard_ssid_tlv->max_ssid_length); /* Empty wildcard ssid with a maxlen will match many or @@ -841,7 +826,6 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, filtered. */ if (!ssid_len && wildcard_ssid_tlv->max_ssid_length) ssid_filter = false; - } /* @@ -850,9 +834,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, * truncate scan results. That is not an issue with an SSID * or BSSID filter applied to the scan results in the firmware. */ - if ((ssid_idx && ssid_filter) - || memcmp(scan_cfg_out->specific_bssid, &zero_mac, - sizeof(zero_mac))) + if ((i && ssid_filter) || + memcmp(scan_cfg_out->specific_bssid, &zero_mac, + sizeof(zero_mac))) *filtered_scan = true; } else { scan_cfg_out->bss_mode = (u8) adapter->scan_mode; @@ -873,7 +857,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, if (num_probes) { dev_dbg(adapter->dev, "info: scan: num_probes = %d\n", - num_probes); + num_probes); num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos; num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); @@ -899,9 +883,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size); - if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) - && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) { + if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) && + (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN)) { ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos; memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap)); ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); @@ -930,8 +914,8 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n"); for (chan_idx = 0; - chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX - && user_scan_in->chan_list[chan_idx].chan_number; + chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX && + user_scan_in->chan_list[chan_idx].chan_number; chan_idx++) { channel = user_scan_in->chan_list[chan_idx].chan_number; @@ -971,9 +955,9 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, } /* Check if we are only scanning the current channel */ - if ((chan_idx == 1) - && (user_scan_in->chan_list[0].chan_number - == priv->curr_bss_params.bss_descriptor.channel)) { + if ((chan_idx == 1) && + (user_scan_in->chan_list[0].chan_number == + priv->curr_bss_params.bss_descriptor.channel)) { *scan_current_only = true; dev_dbg(adapter->dev, "info: Scan: Scanning current channel only\n"); @@ -981,7 +965,7 @@ mwifiex_scan_setup_scan_config(struct mwifiex_private *priv, } else { dev_dbg(adapter->dev, - "info: Scan: Creating full region channel list\n"); + "info: Scan: Creating full region channel list\n"); mwifiex_scan_create_channel_list(priv, user_scan_in, scan_chan_list, *filtered_scan); @@ -1013,7 +997,7 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, *tlv_data = NULL; dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n", - tlv_buf_size); + tlv_buf_size); while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) { @@ -1110,8 +1094,9 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->ssid.ssid_len = element_len; memcpy(bss_entry->ssid.ssid, (current_ptr + 2), element_len); - dev_dbg(adapter->dev, "info: InterpretIE: ssid: " - "%-32s\n", bss_entry->ssid.ssid); + dev_dbg(adapter->dev, + "info: InterpretIE: ssid: %-32s\n", + bss_entry->ssid.ssid); break; case WLAN_EID_SUPP_RATES: @@ -1199,13 +1184,13 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->bcn_wpa_ie = (struct ieee_types_vendor_specific *) current_ptr; - bss_entry->wpa_offset = (u16) (current_ptr - - bss_entry->beacon_buf); + bss_entry->wpa_offset = (u16) + (current_ptr - bss_entry->beacon_buf); } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, sizeof(wmm_oui))) { if (total_ie_len == - sizeof(struct ieee_types_wmm_parameter) - || total_ie_len == + sizeof(struct ieee_types_wmm_parameter) || + total_ie_len == sizeof(struct ieee_types_wmm_info)) /* * Only accept and copy the WMM IE if @@ -1326,14 +1311,14 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, } scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), - GFP_KERNEL); + GFP_KERNEL); if (!scan_cfg_out) { dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); return -ENOMEM; } buf_size = sizeof(struct mwifiex_chan_scan_param_set) * - MWIFIEX_USER_SCAN_CHAN_MAX; + MWIFIEX_USER_SCAN_CHAN_MAX; scan_chan_list = kzalloc(buf_size, GFP_KERNEL); if (!scan_chan_list) { dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); @@ -1341,10 +1326,9 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, return -ENOMEM; } - mwifiex_scan_setup_scan_config(priv, user_scan_in, - &scan_cfg_out->config, &chan_list_out, - scan_chan_list, &max_chan_per_scan, - &filtered_scan, &scan_current_chan_only); + mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config, + &chan_list_out, scan_chan_list, &max_chan_per_scan, + &filtered_scan, &scan_current_chan_only); ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan, &scan_cfg_out->config, chan_list_out, @@ -1355,10 +1339,10 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); if (!list_empty(&adapter->scan_pending_q)) { cmd_node = list_first_entry(&adapter->scan_pending_q, - struct cmd_ctrl_node, list); + struct cmd_ctrl_node, list); list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); + flags); adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); @@ -1444,8 +1428,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv, if (!bss_desc) return -1; - if ((mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv, - (u8) bss_desc->bss_band, (u16) bss_desc->channel))) { + if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band, + (u16) bss_desc->channel, 0))) { switch (priv->bss_mode) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: @@ -1524,7 +1508,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, - sizeof(priv->curr_bss_params.bss_descriptor)); + sizeof(priv->curr_bss_params.bss_descriptor)); mwifiex_save_curr_bcn(priv); spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); @@ -1575,7 +1559,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, struct cfg80211_bss *bss; is_bgscan_resp = (le16_to_cpu(resp->command) - == HostCmd_CMD_802_11_BG_SCAN_QUERY); + == HostCmd_CMD_802_11_BG_SCAN_QUERY); if (is_bgscan_resp) scan_rsp = &resp->params.bg_scan_query_resp.scan_resp; else @@ -1584,20 +1568,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) { dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", - scan_rsp->number_of_sets); + scan_rsp->number_of_sets); ret = -1; goto done; } bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n", - bytes_left); + bytes_left); scan_resp_size = le16_to_cpu(resp->size); dev_dbg(adapter->dev, "info: SCAN_RESP: returned %d APs before parsing\n", - scan_rsp->number_of_sets); + scan_rsp->number_of_sets); bss_info = scan_rsp->bss_desc_and_tlv_buffer; @@ -1635,7 +1619,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, s32 rssi; const u8 *ie_buf; size_t ie_len; - int channel = -1; + u16 channel = 0; u64 network_tsf = 0; u16 beacon_size = 0; u32 curr_bcn_bytes; @@ -1673,7 +1657,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, * and capability information */ if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) { - dev_err(adapter->dev, "InterpretIE: not enough bytes left\n"); + dev_err(adapter->dev, + "InterpretIE: not enough bytes left\n"); continue; } bcn_param = (struct mwifiex_bcn_param *)current_ptr; @@ -1683,20 +1668,20 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, memcpy(bssid, bcn_param->bssid, ETH_ALEN); rssi = (s32) (bcn_param->rssi); - dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", - rssi); + dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", rssi); beacon_period = le16_to_cpu(bcn_param->beacon_period); cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap); dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n", - cap_info_bitmap); + cap_info_bitmap); /* Rest of the current buffer are IE's */ ie_buf = current_ptr; ie_len = curr_bcn_bytes; - dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP" - " = %d\n", curr_bcn_bytes); + dev_dbg(adapter->dev, + "info: InterpretIE: IELength for this AP = %d\n", + curr_bcn_bytes); while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) { u8 element_id, element_len; @@ -1705,8 +1690,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, element_len = *(current_ptr + 1); if (curr_bcn_bytes < element_len + sizeof(struct ieee_types_header)) { - dev_err(priv->adapter->dev, "%s: in processing" - " IE, bytes left < IE length\n", + dev_err(priv->adapter->dev, + "%s: bytes left < IE length\n", __func__); goto done; } @@ -1730,10 +1715,10 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, */ if (tsf_tlv) memcpy(&network_tsf, - &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], - sizeof(network_tsf)); + &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE], + sizeof(network_tsf)); - if (channel != -1) { + if (channel) { struct ieee80211_channel *chan; u8 band; @@ -1746,8 +1731,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, & (BIT(0) | BIT(1))); } - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211( - priv, (u8)band, (u16)channel); + cfp = mwifiex_get_cfp(priv, band, channel, 0); freq = cfp ? cfp->freq : 0; @@ -1761,13 +1745,15 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, *(u8 *)bss->priv = band; cfg80211_put_bss(bss); - if (priv->media_connected && !memcmp(bssid, - priv->curr_bss_params.bss_descriptor - .mac_address, ETH_ALEN)) - mwifiex_update_curr_bss_params(priv, - bssid, rssi, ie_buf, - ie_len, beacon_period, - cap_info_bitmap, band); + if (priv->media_connected && + !memcmp(bssid, + priv->curr_bss_params.bss_descriptor + .mac_address, ETH_ALEN)) + mwifiex_update_curr_bss_params + (priv, bssid, rssi, + ie_buf, ie_len, + beacon_period, + cap_info_bitmap, band); } } else { dev_dbg(adapter->dev, "missing BSS channel IE\n"); @@ -1794,8 +1780,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, } if (priv->user_scan_cfg) { - dev_dbg(priv->adapter->dev, "info: %s: sending scan " - "results\n", __func__); + dev_dbg(priv->adapter->dev, + "info: %s: sending scan results\n", __func__); cfg80211_scan_done(priv->scan_request, 0); priv->scan_request = NULL; kfree(priv->user_scan_cfg); @@ -1860,7 +1846,7 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, * firmware, filtered on a specific SSID. */ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; @@ -1886,8 +1872,8 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, return -ENOMEM; } - memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid, - req_ssid->ssid_len); + scan_cfg->ssid_list = req_ssid; + scan_cfg->num_ssids = 1; ret = mwifiex_scan_networks(priv, scan_cfg); @@ -1905,13 +1891,13 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, * scan, depending upon whether an SSID is provided or not. */ int mwifiex_request_scan(struct mwifiex_private *priv, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { int ret; if (down_interruptible(&priv->async_sem)) { dev_err(priv->adapter->dev, "%s: acquire semaphore\n", - __func__); + __func__); return -1; } priv->scan_pending_on_block = true; @@ -1996,21 +1982,21 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) /* allocate beacon buffer at 1st time; or if it's size has changed */ if (!priv->curr_bcn_buf || - priv->curr_bcn_size != curr_bss->beacon_buf_size) { + priv->curr_bcn_size != curr_bss->beacon_buf_size) { priv->curr_bcn_size = curr_bss->beacon_buf_size; kfree(priv->curr_bcn_buf); priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, - GFP_KERNEL); + GFP_ATOMIC); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, - "failed to alloc curr_bcn_buf\n"); + "failed to alloc curr_bcn_buf\n"); return; } } memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf, - curr_bss->beacon_buf_size); + curr_bss->beacon_buf_size); dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n", priv->curr_bcn_size); diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d39d8457f25..f8012e2b7f7 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -67,13 +67,11 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) struct sdio_mmc_card *card = NULL; pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n", - func->vendor, func->device, func->class, func->num); + func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); - if (!card) { - pr_err("%s: failed to alloc memory\n", __func__); + if (!card) return -ENOMEM; - } card->func = func; @@ -112,6 +110,7 @@ mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; + struct mwifiex_private *priv; int i; pr_debug("info: SDIO func num=%d\n", func->num); @@ -131,15 +130,12 @@ mwifiex_sdio_remove(struct sdio_func *func) for (i = 0; i < adapter->priv_num; i++) if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) && - adapter->priv[i]->media_connected) + adapter->priv[i]->media_connected) mwifiex_deauthenticate(adapter->priv[i], NULL); - mwifiex_disable_auto_ds(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY)); - - mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_ANY), - MWIFIEX_FUNC_SHUTDOWN); + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); + mwifiex_disable_auto_ds(priv); + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); @@ -169,7 +165,7 @@ static int mwifiex_sdio_suspend(struct device *dev) if (func) { pm_flag = sdio_get_host_pm_caps(func); pr_debug("cmd: %s: suspend: PM flag = 0x%x\n", - sdio_func_id(func), pm_flag); + sdio_func_id(func), pm_flag); if (!(pm_flag & MMC_PM_KEEP_POWER)) { pr_err("%s: cannot remain alive while host is" " suspended\n", sdio_func_id(func)); @@ -363,12 +359,11 @@ static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, { struct sdio_mmc_card *card = adapter->card; int ret = -1; - u8 blk_mode = - (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; + u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE + : BLOCK_MODE; u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; - u32 blk_cnt = - (blk_mode == - BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len; + u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) + : len; u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); if (claim) @@ -472,8 +467,7 @@ static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter, i++; dev_err(adapter->dev, "host_to_card, write iomem" " (%d) failed: %d\n", i, ret); - if (mwifiex_write_reg(adapter, - CONFIGURATION_REG, 0x04)) + if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) dev_err(adapter->dev, "write CFG reg failed\n"); ret = -1; @@ -507,11 +501,11 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK); *port = CTRL_PORT; dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n", - *port, card->mp_rd_bitmap); + *port, card->mp_rd_bitmap); } else { if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) { - card->mp_rd_bitmap &= - (u16) (~(1 << card->curr_rd_port)); + card->mp_rd_bitmap &= (u16) + (~(1 << card->curr_rd_port)); *port = card->curr_rd_port; if (++card->curr_rd_port == MAX_PORT) @@ -522,7 +516,7 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n", - *port, rd_bitmap, card->mp_rd_bitmap); + *port, rd_bitmap, card->mp_rd_bitmap); } return 0; } @@ -556,14 +550,14 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port) if (*port == CTRL_PORT) { dev_err(adapter->dev, "invalid data port=%d cur port=%d" - " mp_wr_bitmap=0x%04x -> 0x%04x\n", - *port, card->curr_wr_port, wr_bitmap, - card->mp_wr_bitmap); + " mp_wr_bitmap=0x%04x -> 0x%04x\n", + *port, card->curr_wr_port, wr_bitmap, + card->mp_wr_bitmap); return -1; } dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n", - *port, wr_bitmap, card->mp_wr_bitmap); + *port, wr_bitmap, card->mp_wr_bitmap); return 0; } @@ -583,11 +577,11 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) else if ((cs & bits) == bits) return 0; - udelay(10); + usleep_range(10, 20); } - dev_err(adapter->dev, "poll card status failed, tries = %d\n", - tries); + dev_err(adapter->dev, "poll card status failed, tries = %d\n", tries); + return -1; } @@ -670,14 +664,14 @@ static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter, if (ret) { dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__, - ret); + ret); return -1; } nb = le16_to_cpu(*(__le16 *) (buffer)); if (nb > npayload) { - dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n", - __func__, nb, npayload); + dev_err(adapter->dev, "%s: invalid packet, nb=%d npayload=%d\n", + __func__, nb, npayload); return -1; } @@ -707,19 +701,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, u32 i = 0; if (!firmware_len) { - dev_err(adapter->dev, "firmware image not found!" - " Terminating download\n"); + dev_err(adapter->dev, + "firmware image not found! Terminating download\n"); return -1; } dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n", - firmware_len); + firmware_len); /* Assume that the allocated buffer is 8-byte aligned */ fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL); if (!fwbuf) { - dev_err(adapter->dev, "unable to alloc buffer for firmware." - " Terminating download\n"); + dev_err(adapter->dev, + "unable to alloc buffer for FW. Terminating dnld\n"); return -ENOMEM; } @@ -731,7 +725,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, DN_LD_CARD_RDY); if (ret) { dev_err(adapter->dev, "FW download with helper:" - " poll status timeout @ %d\n", offset); + " poll status timeout @ %d\n", offset); goto done; } @@ -743,17 +737,19 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0, &base0); if (ret) { - dev_err(adapter->dev, "dev BASE0 register read" - " failed: base0=0x%04X(%d). Terminating " - "download\n", base0, base0); + dev_err(adapter->dev, + "dev BASE0 register read failed: " + "base0=%#04X(%d). Terminating dnld\n", + base0, base0); goto done; } ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1, &base1); if (ret) { - dev_err(adapter->dev, "dev BASE1 register read" - " failed: base1=0x%04X(%d). Terminating " - "download\n", base1, base1); + dev_err(adapter->dev, + "dev BASE1 register read failed: " + "base1=%#04X(%d). Terminating dnld\n", + base1, base1); goto done; } len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff)); @@ -761,14 +757,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (len) break; - udelay(10); + usleep_range(10, 20); } if (!len) { break; } else if (len > MWIFIEX_UPLD_SIZE) { - dev_err(adapter->dev, "FW download failed @ %d," - " invalid length %d\n", offset, len); + dev_err(adapter->dev, + "FW dnld failed @ %d, invalid length %d\n", + offset, len); ret = -1; goto done; } @@ -778,13 +775,14 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (len & BIT(0)) { i++; if (i > MAX_WRITE_IOMEM_RETRY) { - dev_err(adapter->dev, "FW download failed @" - " %d, over max retry count\n", offset); + dev_err(adapter->dev, + "FW dnld failed @ %d, over max retry\n", + offset); ret = -1; goto done; } dev_err(adapter->dev, "CRC indicated by the helper:" - " len = 0x%04X, txlen = %d\n", len, txlen); + " len = 0x%04X, txlen = %d\n", len, txlen); len &= ~BIT(0); /* Setting this to 0 to resend from same offset */ txlen = 0; @@ -796,8 +794,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, if (firmware_len - offset < txlen) txlen = firmware_len - offset; - tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - - 1) / MWIFIEX_SDIO_BLOCK_SIZE; + tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1) + / MWIFIEX_SDIO_BLOCK_SIZE; /* Copy payload to buffer */ memmove(fwbuf, &firmware[offset], txlen); @@ -807,8 +805,9 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, MWIFIEX_SDIO_BLOCK_SIZE, adapter->ioport); if (ret) { - dev_err(adapter->dev, "FW download, write iomem (%d)" - " failed @ %d\n", i, offset); + dev_err(adapter->dev, + "FW download, write iomem (%d) failed @ %d\n", + i, offset); if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04)) dev_err(adapter->dev, "write CFG reg failed\n"); @@ -820,7 +819,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, } while (true); dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", - offset); + offset); ret = 0; done: @@ -912,7 +911,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) card = sdio_get_drvdata(func); if (!card || !card->adapter) { pr_debug("int: func=%p card=%p adapter=%p\n", - func, card, card ? card->adapter : NULL); + func, card, card ? card->adapter : NULL); return; } adapter = card->adapter; @@ -955,10 +954,12 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, if (adapter->ps_state == PS_STATE_SLEEP_CFM) mwifiex_process_sleep_confirm_resp(adapter, - skb->data, skb->len); + skb->data, + skb->len); - memcpy(cmd_buf, skb->data, min_t(u32, - MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + memcpy(cmd_buf, skb->data, + min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, + skb->len)); dev_kfree_skb_any(skb); } else { @@ -1016,7 +1017,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (port == CTRL_PORT) { /* Read the command Resp without aggr */ dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " - "response\n", __func__); + "response\n", __func__); f_do_rx_cur = 1; goto rx_curr_single; @@ -1024,7 +1025,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (!card->mpa_rx.enabled) { dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n", - __func__); + __func__); f_do_rx_cur = 1; goto rx_curr_single; @@ -1071,7 +1072,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || MP_RX_AGGR_PORT_LIMIT_REACHED(card)) { dev_dbg(adapter->dev, "info: %s: aggregated packet " - "limit reached\n", __func__); + "limit reached\n", __func__); /* No more pkts allowed in Aggr buf, rx it */ f_do_rx_aggr = 1; } @@ -1080,7 +1081,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, if (f_do_rx_aggr) { /* do aggr RX now */ dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", - card->mpa_rx.pkt_cnt); + card->mpa_rx.pkt_cnt); if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, card->mpa_rx.buf_len, @@ -1194,7 +1195,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8; card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L]; dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n", - card->mp_wr_bitmap); + card->mp_wr_bitmap); if (adapter->data_sent && (card->mp_wr_bitmap & card->mp_data_port_mask)) { dev_dbg(adapter->dev, @@ -1216,12 +1217,12 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) } dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", - adapter->cmd_sent, adapter->data_sent); + adapter->cmd_sent, adapter->data_sent); if (sdio_ireg & UP_LD_HOST_INT_STATUS) { card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8; card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L]; dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n", - card->mp_rd_bitmap); + card->mp_rd_bitmap); while (true) { ret = mwifiex_get_rd_port(adapter, &port); @@ -1235,15 +1236,15 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) rx_len = ((u16) card->mp_regs[len_reg_u]) << 8; rx_len |= (u16) card->mp_regs[len_reg_l]; dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n", - port, rx_len); + port, rx_len); rx_blocks = (rx_len + MWIFIEX_SDIO_BLOCK_SIZE - 1) / MWIFIEX_SDIO_BLOCK_SIZE; - if (rx_len <= INTF_HEADER_LEN - || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > - MWIFIEX_RX_DATA_BUF_SIZE) { + if (rx_len <= INTF_HEADER_LEN || + (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > + MWIFIEX_RX_DATA_BUF_SIZE) { dev_err(adapter->dev, "invalid rx_len=%d\n", - rx_len); + rx_len); return -1; } rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); @@ -1252,42 +1253,42 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) if (!skb) { dev_err(adapter->dev, "%s: failed to alloc skb", - __func__); + __func__); return -1; } skb_put(skb, rx_len); dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n", - rx_len, skb->len); + rx_len, skb->len); if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, port)) { u32 cr = 0; dev_err(adapter->dev, "card_to_host_mpa failed:" - " int status=%#x\n", sdio_ireg); + " int status=%#x\n", sdio_ireg); if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) dev_err(adapter->dev, - "read CFG reg failed\n"); + "read CFG reg failed\n"); dev_dbg(adapter->dev, - "info: CFG reg val = %d\n", cr); + "info: CFG reg val = %d\n", cr); if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04))) dev_err(adapter->dev, - "write CFG reg failed\n"); + "write CFG reg failed\n"); dev_dbg(adapter->dev, "info: write success\n"); if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) dev_err(adapter->dev, - "read CFG reg failed\n"); + "read CFG reg failed\n"); dev_dbg(adapter->dev, - "info: CFG reg val =%x\n", cr); + "info: CFG reg val =%x\n", cr); return -1; } } @@ -1323,7 +1324,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", - __func__); + __func__); f_send_cur_buf = 1; goto tx_curr_single; @@ -1332,7 +1333,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (next_pkt_len) { /* More pkt in TX queue */ dev_dbg(adapter->dev, "info: %s: more packets in queue.\n", - __func__); + __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) && @@ -1340,9 +1341,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, f_precopy_cur_buf = 1; if (!(card->mp_wr_bitmap & - (1 << card->curr_wr_port)) - || !MP_TX_AGGR_BUF_HAS_ROOM( - card, pkt_len + next_pkt_len)) + (1 << card->curr_wr_port)) || + !MP_TX_AGGR_BUF_HAS_ROOM( + card, pkt_len + next_pkt_len)) f_send_aggr_buf = 1; } else { /* No room in Aggr buf, send it */ @@ -1356,8 +1357,8 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, f_postcopy_cur_buf = 1; } } else { - if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) - && (card->mp_wr_bitmap & (1 << card->curr_wr_port))) + if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) && + (card->mp_wr_bitmap & (1 << card->curr_wr_port))) f_precopy_cur_buf = 1; else f_send_cur_buf = 1; @@ -1365,7 +1366,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, } else { /* Last pkt in TX queue */ dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n", - __func__); + __func__); if (MP_TX_AGGR_IN_PROGRESS(card)) { /* some packs in Aggr buf already */ @@ -1383,7 +1384,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (f_precopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: precopy current buffer\n", - __func__); + __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) || @@ -1394,7 +1395,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, if (f_send_aggr_buf) { dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", - __func__, + __func__, card->mpa_tx.start_port, card->mpa_tx.ports); ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, card->mpa_tx.buf_len, @@ -1408,14 +1409,14 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, tx_curr_single: if (f_send_cur_buf) { dev_dbg(adapter->dev, "data: %s: send current buffer %d\n", - __func__, port); + __func__, port); ret = mwifiex_write_data_to_card(adapter, payload, pkt_len, adapter->ioport + port); } if (f_postcopy_cur_buf) { dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n", - __func__); + __func__); MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port); } @@ -1460,7 +1461,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, ret = mwifiex_get_wr_port_data(adapter, &port); if (ret) { dev_err(adapter->dev, "%s: no wr_port available\n", - __func__); + __func__); return ret; } } else { @@ -1470,7 +1471,7 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, if (pkt_len <= INTF_HEADER_LEN || pkt_len > MWIFIEX_UPLD_SIZE) dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", - __func__, payload, pkt_len); + __func__, payload, pkt_len); } /* Transfer data to card */ @@ -1478,10 +1479,11 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, if (tx_param) ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, - port, tx_param->next_pkt_len); + port, tx_param->next_pkt_len + ); else ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len, - port, 0); + port, 0); if (ret) { if (type == MWIFIEX_TYPE_CMD) @@ -1734,7 +1736,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) card->curr_wr_port = 1; dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n", - port, card->mp_data_port_mask); + port, card->mp_data_port_mask); } static struct mwifiex_if_ops sdio_ops = { diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 6e443ffa046..6c8e4594b48 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -103,76 +103,32 @@ static int mwifiex_cmd_mac_control(struct mwifiex_private *priv, static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, - u32 *ul_temp) + u16 *ul_temp) { struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib; dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB); cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib) - - 1 + S_DS_GEN); + - 1 + S_DS_GEN); + snmp_mib->oid = cpu_to_le16((u16)cmd_oid); if (cmd_action == HostCmd_ACT_GEN_GET) { snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET); snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + MAX_SNMP_BUF_SIZE); + le16_add_cpu(&cmd->size, MAX_SNMP_BUF_SIZE); + } else if (cmd_action == HostCmd_ACT_GEN_SET) { + snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); + snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); + *((__le16 *) (snmp_mib->value)) = cpu_to_le16(*ul_temp); + le16_add_cpu(&cmd->size, sizeof(u16)); } - switch (cmd_oid) { - case FRAG_THRESH_I: - snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - case RTS_THRESH_I: - snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *(__le16 *) (snmp_mib->value) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - - case SHORT_RETRY_LIM_I: - snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - case DOT11D_I: - snmp_mib->oid = cpu_to_le16((u16) DOT11D_I); - if (cmd_action == HostCmd_ACT_GEN_SET) { - snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET); - snmp_mib->buf_size = cpu_to_le16(sizeof(u16)); - *((__le16 *) (snmp_mib->value)) = - cpu_to_le16((u16) *ul_temp); - cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) - + sizeof(u16)); - } - break; - default: - break; - } dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x," " Value=0x%x\n", - cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), - le16_to_cpu(*(__le16 *) snmp_mib->value)); + cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size), + le16_to_cpu(*(__le16 *) snmp_mib->value)); return 0; } @@ -218,8 +174,8 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg + sizeof(struct host_cmd_ds_tx_rate_cfg)); rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE); - rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) - - sizeof(struct mwifiex_ie_types_header)); + rate_scope->length = cpu_to_le16 + (sizeof(*rate_scope) - sizeof(struct mwifiex_ie_types_header)); if (pbitmap_rates != NULL) { rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]); rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]); @@ -241,7 +197,7 @@ static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv, } rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope + - sizeof(struct mwifiex_rate_scope)); + sizeof(struct mwifiex_rate_scope)); rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL); rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode)); rate_drop->rate_drop_mode = 0; @@ -328,22 +284,22 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH); if (!hs_activate && - (hscfg_param->conditions - != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) - && ((adapter->arp_filter_size > 0) - && (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { + (hscfg_param->conditions != cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) && + ((adapter->arp_filter_size > 0) && + (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) { dev_dbg(adapter->dev, "cmd: Attach %d bytes ArpFilter to HSCfg cmd\n", - adapter->arp_filter_size); + adapter->arp_filter_size); memcpy(((u8 *) hs_cfg) + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh), adapter->arp_filter, adapter->arp_filter_size); - cmd->size = cpu_to_le16(adapter->arp_filter_size + - sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) - + S_DS_GEN); + cmd->size = cpu_to_le16 + (adapter->arp_filter_size + + sizeof(struct host_cmd_ds_802_11_hs_cfg_enh) + + S_DS_GEN); } else { cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct - host_cmd_ds_802_11_hs_cfg_enh)); + host_cmd_ds_802_11_hs_cfg_enh)); } if (hs_activate) { hs_cfg->action = cpu_to_le16(HS_ACTIVATE); @@ -511,7 +467,7 @@ mwifiex_set_keyparamset_wep(struct mwifiex_private *priv, key_param_set = (struct mwifiex_ie_type_key_param_set *) ((u8 *)key_param_set + - cur_key_param_len); + cur_key_param_len); } else if (!priv->wep_key[i].key_length) { continue; } else { @@ -571,13 +527,13 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, if (enc_key->is_wapi_key) { dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_WAPI); + cpu_to_le16(KEY_TYPE_ID_WAPI); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_ENABLED); + cpu_to_le16(!KEY_ENABLED); key_material->key_param_set.key[0] = enc_key->key_index; if (!priv->sec_info.wapi_key_on) @@ -597,9 +553,9 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, } key_material->key_param_set.type = - cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); key_material->key_param_set.key_len = - cpu_to_le16(WAPI_KEY_LEN); + cpu_to_le16(WAPI_KEY_LEN); memcpy(&key_material->key_param_set.key[2], enc_key->key_material, enc_key->key_len); memcpy(&key_material->key_param_set.key[2 + enc_key->key_len], @@ -609,49 +565,49 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) + sizeof(struct mwifiex_ie_types_header); - cmd->size = cpu_to_le16(key_param_len + - sizeof(key_material->action) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(key_material->action) + + S_DS_GEN + key_param_len); return ret; } if (enc_key->key_len == WLAN_KEY_LEN_CCMP) { dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_AES); + cpu_to_le16(KEY_TYPE_ID_AES); if (cmd_oid == KEY_INFO_ENABLED) key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); else key_material->key_param_set.key_info = - cpu_to_le16(!KEY_ENABLED); + cpu_to_le16(!KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* AES pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* AES group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_MCAST); + cpu_to_le16(KEY_MCAST); } else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) { dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n"); key_material->key_param_set.key_type_id = - cpu_to_le16(KEY_TYPE_ID_TKIP); + cpu_to_le16(KEY_TYPE_ID_TKIP); key_material->key_param_set.key_info = - cpu_to_le16(KEY_ENABLED); + cpu_to_le16(KEY_ENABLED); if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST) /* TKIP pairwise key: unicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_UNICAST); + cpu_to_le16(KEY_UNICAST); else /* TKIP group key: multicast */ key_material->key_param_set.key_info |= - cpu_to_le16(KEY_MCAST); + cpu_to_le16(KEY_MCAST); } if (key_material->key_param_set.key_type_id) { key_material->key_param_set.type = - cpu_to_le16(TLV_TYPE_KEY_MATERIAL); + cpu_to_le16(TLV_TYPE_KEY_MATERIAL); key_material->key_param_set.key_len = - cpu_to_le16((u16) enc_key->key_len); + cpu_to_le16((u16) enc_key->key_len); memcpy(key_material->key_param_set.key, enc_key->key_material, enc_key->key_len); key_material->key_param_set.length = @@ -659,10 +615,10 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv, KEYPARAMSET_FIXED_LEN); key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN) - + sizeof(struct mwifiex_ie_types_header); + + sizeof(struct mwifiex_ie_types_header); - cmd->size = cpu_to_le16(key_param_len + - sizeof(key_material->action) + S_DS_GEN); + cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN + + key_param_len); } return ret; @@ -699,21 +655,22 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, /* Set domain info fields */ domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY); memcpy(domain->country_code, adapter->domain_reg.country_code, - sizeof(domain->country_code)); + sizeof(domain->country_code)); - domain->header.len = cpu_to_le16((no_of_triplet * - sizeof(struct ieee80211_country_ie_triplet)) + - sizeof(domain->country_code)); + domain->header.len = + cpu_to_le16((no_of_triplet * + sizeof(struct ieee80211_country_ie_triplet)) + + sizeof(domain->country_code)); if (no_of_triplet) { memcpy(domain->triplet, adapter->domain_reg.triplet, - no_of_triplet * - sizeof(struct ieee80211_country_ie_triplet)); + no_of_triplet * sizeof(struct + ieee80211_country_ie_triplet)); cmd->size = cpu_to_le16(sizeof(domain_info->action) + - le16_to_cpu(domain->header.len) + - sizeof(struct mwifiex_ie_types_header) - + S_DS_GEN); + le16_to_cpu(domain->header.len) + + sizeof(struct mwifiex_ie_types_header) + + S_DS_GEN); } else { cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN); } @@ -742,8 +699,8 @@ static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, + S_DS_GEN); if (cmd_action == HostCmd_ACT_GEN_SET) { - if ((priv->adapter->adhoc_start_band & BAND_A) - || (priv->adapter->adhoc_start_band & BAND_AN)) + if ((priv->adapter->adhoc_start_band & BAND_A) || + (priv->adapter->adhoc_start_band & BAND_AN)) rf_chan->rf_type = cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); @@ -821,7 +778,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN); mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd-> - params.mac_reg; + params.mac_reg; mac_reg->action = cpu_to_le16(cmd_action); mac_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -833,8 +790,8 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_bbp_reg_access *bbp_reg; cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN); - bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd-> - params.bbp_reg; + bbp_reg = (struct host_cmd_ds_bbp_reg_access *) + &cmd->params.bbp_reg; bbp_reg->action = cpu_to_le16(cmd_action); bbp_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); @@ -846,11 +803,10 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *rf_reg; cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN); - rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> - params.rf_reg; + rf_reg = (struct host_cmd_ds_rf_reg_access *) + &cmd->params.rf_reg; rf_reg->action = cpu_to_le16(cmd_action); - rf_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + rf_reg->offset = cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); rf_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -863,7 +819,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, params.pmic_reg; pmic_reg->action = cpu_to_le16(cmd_action); pmic_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); pmic_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -872,11 +828,11 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, struct host_cmd_ds_rf_reg_access *cau_reg; cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN); - cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd-> - params.rf_reg; + cau_reg = (struct host_cmd_ds_rf_reg_access *) + &cmd->params.rf_reg; cau_reg->action = cpu_to_le16(cmd_action); cau_reg->offset = - cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); + cpu_to_le16((u16) le32_to_cpu(reg_rw->offset)); cau_reg->value = (u8) le32_to_cpu(reg_rw->value); break; } @@ -912,7 +868,7 @@ static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd, */ static int mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, u16 action) + struct host_cmd_ds_command *cmd, u16 action) { struct host_cmd_ds_pcie_details *host_spec = &cmd->params.pcie_host_spec; @@ -926,29 +882,25 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv, memset(host_spec, 0, sizeof(struct host_cmd_ds_pcie_details)); - if (action == HostCmd_ACT_GEN_SET) { - /* Send the ring base addresses and count to firmware */ - host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); - host_spec->txbd_addr_hi = - (u32)(((u64)card->txbd_ring_pbase)>>32); - host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; - host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); - host_spec->rxbd_addr_hi = - (u32)(((u64)card->rxbd_ring_pbase)>>32); - host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; - host_spec->evtbd_addr_lo = - (u32)(card->evtbd_ring_pbase); - host_spec->evtbd_addr_hi = - (u32)(((u64)card->evtbd_ring_pbase)>>32); - host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; - if (card->sleep_cookie) { - buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); - host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; - host_spec->sleep_cookie_addr_hi = - (u32) (((u64)*buf_pa) >> 32); - dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: " - "0x%x\n", host_spec->sleep_cookie_addr_lo); - } + if (action != HostCmd_ACT_GEN_SET) + return 0; + + /* Send the ring base addresses and count to firmware */ + host_spec->txbd_addr_lo = (u32)(card->txbd_ring_pbase); + host_spec->txbd_addr_hi = (u32)(((u64)card->txbd_ring_pbase)>>32); + host_spec->txbd_count = MWIFIEX_MAX_TXRX_BD; + host_spec->rxbd_addr_lo = (u32)(card->rxbd_ring_pbase); + host_spec->rxbd_addr_hi = (u32)(((u64)card->rxbd_ring_pbase)>>32); + host_spec->rxbd_count = MWIFIEX_MAX_TXRX_BD; + host_spec->evtbd_addr_lo = (u32)(card->evtbd_ring_pbase); + host_spec->evtbd_addr_hi = (u32)(((u64)card->evtbd_ring_pbase)>>32); + host_spec->evtbd_count = MWIFIEX_MAX_EVT_BD; + if (card->sleep_cookie) { + buf_pa = MWIFIEX_SKB_PACB(card->sleep_cookie); + host_spec->sleep_cookie_addr_lo = (u32) *buf_pa; + host_spec->sleep_cookie_addr_hi = (u32) (((u64)*buf_pa) >> 32); + dev_dbg(priv->adapter->dev, "sleep_cook_lo phy addr: 0x%x\n", + host_spec->sleep_cookie_addr_lo); } return 0; @@ -1080,12 +1032,12 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, break; case HostCmd_CMD_802_11_KEY_MATERIAL: ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr, - cmd_action, cmd_oid, - data_buf); + cmd_action, cmd_oid, + data_buf); break; case HostCmd_CMD_802_11D_DOMAIN_INFO: ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr, - cmd_action); + cmd_action); break; case HostCmd_CMD_RECONFIGURE_TX_BUFF: ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action, @@ -1096,8 +1048,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, data_buf); break; case HostCmd_CMD_11N_CFG: - ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, - data_buf); + ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action, data_buf); break; case HostCmd_CMD_WMM_GET_STATUS: dev_dbg(priv->adapter->dev, @@ -1175,8 +1126,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) if (first_sta) { if (priv->adapter->iface_type == MWIFIEX_PCIE) { ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_PCIE_DESC_DETAILS, - HostCmd_ACT_GEN_SET, 0, NULL); + HostCmd_CMD_PCIE_DESC_DETAILS, + HostCmd_ACT_GEN_SET, 0, NULL); if (ret) return -1; } diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index e812db8b695..4da19ed0f07 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -49,7 +49,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, unsigned long flags; dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n", - resp->command, resp->result); + resp->command, resp->result); if (adapter->curr_cmd->wait_q_enabled) adapter->cmd_wait_q.status = -1; @@ -57,13 +57,13 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, switch (le16_to_cpu(resp->command)) { case HostCmd_CMD_802_11_PS_MODE_ENH: pm = &resp->params.psmode_enh; - dev_err(adapter->dev, "PS_MODE_ENH cmd failed: " - "result=0x%x action=0x%X\n", - resp->result, le16_to_cpu(pm->action)); + dev_err(adapter->dev, + "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n", + resp->result, le16_to_cpu(pm->action)); /* We do not re-try enter-ps command in ad-hoc mode. */ if (le16_to_cpu(pm->action) == EN_AUTO_PS && - (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && - priv->bss_mode == NL80211_IFTYPE_ADHOC) + (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) && + priv->bss_mode == NL80211_IFTYPE_ADHOC) adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; break; @@ -123,7 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv, struct mwifiex_ds_get_signal *signal) { struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = - &resp->params.rssi_info_rsp; + &resp->params.rssi_info_rsp; priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); @@ -191,8 +191,8 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, u32 ul_temp; dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x," - " query_type = %#x, buf size = %#x\n", - oid, query_type, le16_to_cpu(smib->buf_size)); + " query_type = %#x, buf size = %#x\n", + oid, query_type, le16_to_cpu(smib->buf_size)); if (query_type == HostCmd_ACT_GEN_GET) { ul_temp = le16_to_cpu(*((__le16 *) (smib->value))); if (data_buf) @@ -210,6 +210,9 @@ static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: SNMP_RESP: TxRetryCount=%u\n", ul_temp); break; + case DTIM_PERIOD_I: + dev_dbg(priv->adapter->dev, + "info: SNMP_RESP: DTIM period=%u\n", ul_temp); default: break; } @@ -324,31 +327,26 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, HostCmd_CMD_802_11_TX_RATE_QUERY, HostCmd_ACT_GEN_GET, 0, NULL); - if (ds_rate) { - if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { - if (priv->is_data_rate_auto) { - ds_rate->is_rate_auto = 1; - } else { - ds_rate->rate = mwifiex_get_rate_index(priv-> - bitmap_rates, - sizeof(priv-> - bitmap_rates)); - if (ds_rate->rate >= - MWIFIEX_RATE_BITMAP_OFDM0 - && ds_rate->rate <= - MWIFIEX_RATE_BITMAP_OFDM7) - ds_rate->rate -= - (MWIFIEX_RATE_BITMAP_OFDM0 - - MWIFIEX_RATE_INDEX_OFDM0); - if (ds_rate->rate >= - MWIFIEX_RATE_BITMAP_MCS0 - && ds_rate->rate <= - MWIFIEX_RATE_BITMAP_MCS127) - ds_rate->rate -= - (MWIFIEX_RATE_BITMAP_MCS0 - - MWIFIEX_RATE_INDEX_MCS0); - } - } + if (!ds_rate) + return ret; + + if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { + if (priv->is_data_rate_auto) { + ds_rate->is_rate_auto = 1; + return ret; + } + ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates, + sizeof(priv->bitmap_rates)); + + if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 && + ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7) + ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 - + MWIFIEX_RATE_INDEX_OFDM0); + + if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 && + ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127) + ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 - + MWIFIEX_RATE_INDEX_MCS0); } return ret; @@ -366,34 +364,32 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) struct mwifiex_types_power_group *pg_tlv_hdr; struct mwifiex_power_group *pg; - if (data_buf) { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) data_buf - + sizeof(struct host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + - sizeof(struct mwifiex_types_power_group)); - length = pg_tlv_hdr->length; - if (length > 0) { + if (!data_buf) + return -1; + + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); + length = pg_tlv_hdr->length; + if (length > 0) { + max_power = pg->power_max; + min_power = pg->power_min; + length -= sizeof(struct mwifiex_power_group); + } + while (length) { + pg++; + if (max_power < pg->power_max) max_power = pg->power_max; - min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - while (length) { - pg++; - if (max_power < pg->power_max) - max_power = pg->power_max; - if (min_power > pg->power_min) - min_power = pg->power_min; + if (min_power > pg->power_min) + min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - } - if (pg_tlv_hdr->length > 0) { - priv->min_tx_power_level = (u8) min_power; - priv->max_tx_power_level = (u8) max_power; - } - } else { - return -1; + length -= sizeof(struct mwifiex_power_group); + } + if (pg_tlv_hdr->length > 0) { + priv->min_tx_power_level = (u8) min_power; + priv->max_tx_power_level = (u8) max_power; } return 0; @@ -417,42 +413,38 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, switch (action) { case HostCmd_ACT_GEN_GET: - { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) - txp_cfg + - sizeof - (struct - host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) - pg_tlv_hdr + - sizeof(struct - mwifiex_types_power_group)); - if (adapter->hw_status == - MWIFIEX_HW_STATUS_INITIALIZING) - mwifiex_get_power_level(priv, txp_cfg); - priv->tx_power_level = (u16) pg->power_min; - break; - } + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + + if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) + mwifiex_get_power_level(priv, txp_cfg); + + priv->tx_power_level = (u16) pg->power_min; + break; + case HostCmd_ACT_GEN_SET: - if (le32_to_cpu(txp_cfg->mode)) { - pg_tlv_hdr = - (struct mwifiex_types_power_group *) ((u8 *) - txp_cfg + - sizeof - (struct - host_cmd_ds_txpwr_cfg)); - pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr - + - sizeof(struct - mwifiex_types_power_group)); - if (pg->power_max == pg->power_min) - priv->tx_power_level = (u16) pg->power_min; - } + if (!le32_to_cpu(txp_cfg->mode)) + break; + + pg_tlv_hdr = (struct mwifiex_types_power_group *) + ((u8 *) txp_cfg + + sizeof(struct host_cmd_ds_txpwr_cfg)); + + pg = (struct mwifiex_power_group *) + ((u8 *) pg_tlv_hdr + + sizeof(struct mwifiex_types_power_group)); + + if (pg->power_max == pg->power_min) + priv->tx_power_level = (u16) pg->power_min; break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n", - action); + action); return 0; } dev_dbg(adapter->dev, @@ -472,7 +464,7 @@ static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_mac_address *cmd_mac_addr = - &resp->params.mac_addr; + &resp->params.mac_addr; memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN); @@ -557,7 +549,7 @@ static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_key_material *key = - &resp->params.key_material; + &resp->params.key_material; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { @@ -588,17 +580,18 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, u16 action = le16_to_cpu(domain_info->action); u8 no_of_triplet; - no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) - - IEEE80211_COUNTRY_STRING_LEN) / - sizeof(struct ieee80211_country_ie_triplet)); + no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) + - IEEE80211_COUNTRY_STRING_LEN) + / sizeof(struct ieee80211_country_ie_triplet)); - dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:" - " no_of_triplet=%d\n", no_of_triplet); + dev_dbg(priv->adapter->dev, + "info: 11D Domain Info Resp: no_of_triplet=%d\n", + no_of_triplet); if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) { dev_warn(priv->adapter->dev, - "11D: invalid number of triplets %d " - "returned!!\n", no_of_triplet); + "11D: invalid number of triplets %d returned\n", + no_of_triplet); return -1; } @@ -632,8 +625,8 @@ static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", - priv->curr_bss_params.bss_descriptor.channel, - new_channel); + priv->curr_bss_params.bss_descriptor.channel, + new_channel); /* Update the channel again */ priv->curr_bss_params.bss_descriptor.channel = new_channel; } @@ -676,90 +669,70 @@ static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp, { struct mwifiex_ds_reg_rw *reg_rw; struct mwifiex_ds_read_eeprom *eeprom; + union reg { + struct host_cmd_ds_mac_reg_access *mac; + struct host_cmd_ds_bbp_reg_access *bbp; + struct host_cmd_ds_rf_reg_access *rf; + struct host_cmd_ds_pmic_reg_access *pmic; + struct host_cmd_ds_802_11_eeprom_access *eeprom; + } r; + + if (!data_buf) + return 0; - if (data_buf) { - reg_rw = data_buf; - eeprom = data_buf; - switch (type) { - case HostCmd_CMD_MAC_REG_ACCESS: - { - struct host_cmd_ds_mac_reg_access *reg; - reg = (struct host_cmd_ds_mac_reg_access *) - &resp->params.mac_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = reg->value; - break; - } - case HostCmd_CMD_BBP_REG_ACCESS: - { - struct host_cmd_ds_bbp_reg_access *reg; - reg = (struct host_cmd_ds_bbp_reg_access *) - &resp->params.bbp_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - - case HostCmd_CMD_RF_REG_ACCESS: - { - struct host_cmd_ds_rf_reg_access *reg; - reg = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_PMIC_REG_ACCESS: - { - struct host_cmd_ds_pmic_reg_access *reg; - reg = (struct host_cmd_ds_pmic_reg_access *) - &resp->params.pmic_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_CAU_REG_ACCESS: - { - struct host_cmd_ds_rf_reg_access *reg; - reg = (struct host_cmd_ds_rf_reg_access *) - &resp->params.rf_reg; - reg_rw->offset = cpu_to_le32( - (u32) le16_to_cpu(reg->offset)); - reg_rw->value = cpu_to_le32((u32) reg->value); - break; - } - case HostCmd_CMD_802_11_EEPROM_ACCESS: - { - struct host_cmd_ds_802_11_eeprom_access - *cmd_eeprom = - (struct host_cmd_ds_802_11_eeprom_access - *) &resp->params.eeprom; - pr_debug("info: EEPROM read len=%x\n", - cmd_eeprom->byte_count); - if (le16_to_cpu(eeprom->byte_count) < - le16_to_cpu( - cmd_eeprom->byte_count)) { - eeprom->byte_count = cpu_to_le16(0); - pr_debug("info: EEPROM read " - "length is too big\n"); - return -1; - } - eeprom->offset = cmd_eeprom->offset; - eeprom->byte_count = cmd_eeprom->byte_count; - if (le16_to_cpu(eeprom->byte_count) > 0) - memcpy(&eeprom->value, - &cmd_eeprom->value, - le16_to_cpu(eeprom->byte_count)); - - break; - } - default: + reg_rw = data_buf; + eeprom = data_buf; + switch (type) { + case HostCmd_CMD_MAC_REG_ACCESS: + r.mac = (struct host_cmd_ds_mac_reg_access *) + &resp->params.mac_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset)); + reg_rw->value = r.mac->value; + break; + case HostCmd_CMD_BBP_REG_ACCESS: + r.bbp = (struct host_cmd_ds_bbp_reg_access *) + &resp->params.bbp_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset)); + reg_rw->value = cpu_to_le32((u32) r.bbp->value); + break; + + case HostCmd_CMD_RF_REG_ACCESS: + r.rf = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); + reg_rw->value = cpu_to_le32((u32) r.bbp->value); + break; + case HostCmd_CMD_PMIC_REG_ACCESS: + r.pmic = (struct host_cmd_ds_pmic_reg_access *) + &resp->params.pmic_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset)); + reg_rw->value = cpu_to_le32((u32) r.pmic->value); + break; + case HostCmd_CMD_CAU_REG_ACCESS: + r.rf = (struct host_cmd_ds_rf_reg_access *) + &resp->params.rf_reg; + reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset)); + reg_rw->value = cpu_to_le32((u32) r.rf->value); + break; + case HostCmd_CMD_802_11_EEPROM_ACCESS: + r.eeprom = (struct host_cmd_ds_802_11_eeprom_access *) + &resp->params.eeprom; + pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count); + if (le16_to_cpu(eeprom->byte_count) < + le16_to_cpu(r.eeprom->byte_count)) { + eeprom->byte_count = cpu_to_le16(0); + pr_debug("info: EEPROM read length is too big\n"); return -1; } + eeprom->offset = r.eeprom->offset; + eeprom->byte_count = r.eeprom->byte_count; + if (le16_to_cpu(eeprom->byte_count) > 0) + memcpy(&eeprom->value, &r.eeprom->value, + le16_to_cpu(r.eeprom->byte_count)); + + break; + default: + return -1; } return 0; } @@ -775,7 +748,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv, struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp = - &(resp->params.ibss_coalescing); + &(resp->params.ibss_coalescing); u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET) @@ -915,20 +888,17 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_RECONFIGURE_TX_BUFF: adapter->tx_buf_size = (u16) le16_to_cpu(resp->params. tx_buf.buff_size); - adapter->tx_buf_size = (adapter->tx_buf_size / - MWIFIEX_SDIO_BLOCK_SIZE) * - MWIFIEX_SDIO_BLOCK_SIZE; + adapter->tx_buf_size = (adapter->tx_buf_size + / MWIFIEX_SDIO_BLOCK_SIZE) + * MWIFIEX_SDIO_BLOCK_SIZE; adapter->curr_tx_buf_size = adapter->tx_buf_size; dev_dbg(adapter->dev, "cmd: max_tx_buf_size=%d, tx_buf_size=%d\n", - adapter->max_tx_buf_size, adapter->tx_buf_size); + adapter->max_tx_buf_size, adapter->tx_buf_size); if (adapter->if_ops.update_mp_end_port) adapter->if_ops.update_mp_end_port(adapter, - le16_to_cpu(resp-> - params. - tx_buf. - mp_end_port)); + le16_to_cpu(resp->params.tx_buf.mp_end_port)); break; case HostCmd_CMD_AMSDU_AGGR_CTRL: ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf); @@ -956,7 +926,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, break; default: dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", - resp->command); + resp->command); break; } diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index d7aa21da84d..cc531b536a5 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -93,15 +93,15 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) */ dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n", - priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); + priv->prev_ssid.ssid, priv->prev_ssid.ssid_len); dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n", - priv->curr_bss_params.bss_descriptor.ssid.ssid, - priv->curr_bss_params.bss_descriptor.ssid.ssid_len); + priv->curr_bss_params.bss_descriptor.ssid.ssid, + priv->curr_bss_params.bss_descriptor.ssid.ssid_len); memcpy(&priv->prev_ssid, &priv->curr_bss_params.bss_descriptor.ssid, - sizeof(struct mwifiex_802_11_ssid)); + sizeof(struct cfg80211_ssid)); memcpy(priv->prev_bssid, priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN); @@ -115,9 +115,9 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) if (adapter->num_cmd_timeout && adapter->curr_cmd) return; priv->media_connected = false; - dev_dbg(adapter->dev, "info: successfully disconnected from" - " %pM: reason code %d\n", priv->cfg_bssid, - WLAN_REASON_DEAUTH_LEAVING); + dev_dbg(adapter->dev, + "info: successfully disconnected from %pM: reason code %d\n", + priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING); if (priv->bss_mode == NL80211_IFTYPE_STATION) { cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING, NULL, 0, GFP_KERNEL); @@ -192,8 +192,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) switch (eventcause) { case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: - dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL," - " ignoring it\n"); + dev_err(adapter->dev, + "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL, ignore it\n"); break; case EVENT_LINK_SENSED: dev_dbg(adapter->dev, "event: LINK_SENSED\n"); @@ -235,8 +235,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) case EVENT_PS_AWAKE: dev_dbg(adapter->dev, "info: EVENT: AWAKE\n"); if (!adapter->pps_uapsd_mode && - priv->media_connected && - adapter->sleep_period.period) { + priv->media_connected && adapter->sleep_period.period) { adapter->pps_uapsd_mode = true; dev_dbg(adapter->dev, "event: PPS/UAPSD mode activated\n"); @@ -244,15 +243,19 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) adapter->tx_lock_flag = false; if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) { if (mwifiex_check_last_packet_indication(priv)) { - if (!adapter->data_sent) { - if (!mwifiex_send_null_packet(priv, - MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET - | - MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) + if (adapter->data_sent) { + adapter->ps_state = PS_STATE_AWAKE; + adapter->pm_wakeup_card_req = false; + adapter->pm_wakeup_fw_try = false; + break; + } + if (!mwifiex_send_null_packet + (priv, + MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | + MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) adapter->ps_state = PS_STATE_SLEEP; return 0; - } } } adapter->ps_state = PS_STATE_AWAKE; @@ -371,12 +374,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_AMSDU_AGGR_CTRL: dev_dbg(adapter->dev, "event: AMSDU_AGGR_CTRL %d\n", - *(u16 *) adapter->event_body); + *(u16 *) adapter->event_body); adapter->tx_buf_size = min(adapter->curr_tx_buf_size, le16_to_cpu(*(__le16 *) adapter->event_body)); dev_dbg(adapter->dev, "event: tx_buf_size %d\n", - adapter->tx_buf_size); + adapter->tx_buf_size); break; case EVENT_WEP_ICV_ERR: @@ -392,7 +395,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; default: dev_dbg(adapter->dev, "event: unknown event id: %#x\n", - eventcause); + eventcause); break; } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index b0fbf5d4fea..d7b11defafe 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -71,7 +71,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) /* Wait for completion */ wait_event_interruptible(adapter->cmd_wait_q.wait, - *(cmd_queued->condition)); + *(cmd_queued->condition)); if (!*(cmd_queued->condition)) cancel_flag = true; @@ -192,7 +192,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, * first. */ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, - struct mwifiex_802_11_ssid *req_ssid) + struct cfg80211_ssid *req_ssid) { int ret; struct mwifiex_adapter *adapter = priv->adapter; @@ -249,15 +249,25 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, * application retrieval */ priv->assoc_rsp_size = 0; ret = mwifiex_associate(priv, bss_desc); + + /* If auth type is auto and association fails using open mode, + * try to connect using shared mode */ + if (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && + priv->sec_info.is_authtype_auto && + priv->sec_info.wep_enabled) { + priv->sec_info.authentication_mode = + NL80211_AUTHTYPE_SHARED_KEY; + ret = mwifiex_associate(priv, bss_desc); + } + if (bss) cfg80211_put_bss(bss); } else { /* Adhoc mode */ /* If the requested SSID matches current SSID, return */ if (bss_desc && bss_desc->ssid.ssid_len && - (!mwifiex_ssid_cmp - (&priv->curr_bss_params.bss_descriptor.ssid, - &bss_desc->ssid))) { + (!mwifiex_ssid_cmp(&priv->curr_bss_params.bss_descriptor. + ssid, &bss_desc->ssid))) { kfree(bss_desc); kfree(beacon_ie); return 0; @@ -339,9 +349,8 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; if (hs_cfg->gap) adapter->hs_cfg.gap = (u8)hs_cfg->gap; - } else if (adapter->hs_cfg.conditions == - cpu_to_le32( - HOST_SLEEP_CFG_CANCEL)) { + } else if (adapter->hs_cfg.conditions + == cpu_to_le32(HOST_SLEEP_CFG_CANCEL)) { /* Return failure if no parameters for HS enable */ status = -1; @@ -363,7 +372,7 @@ static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, cpu_to_le32(prev_cond); } else { adapter->hs_cfg.conditions = - cpu_to_le32(hs_cfg->conditions); + cpu_to_le32(hs_cfg->conditions); adapter->hs_cfg.gpio = (u8)hs_cfg->gpio; adapter->hs_cfg.gap = (u8)hs_cfg->gap; } @@ -416,11 +425,11 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) adapter->hs_activate_wait_q_woken = false; - memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param)); + memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg)); hscfg.is_invoke_hostcmd = true; if (mwifiex_set_hs_params(mwifiex_get_priv(adapter, - MWIFIEX_BSS_ROLE_STA), + MWIFIEX_BSS_ROLE_STA), HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD, &hscfg)) { dev_err(adapter->dev, "IOCTL request HS enable failed\n"); @@ -428,7 +437,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } wait_event_interruptible(adapter->hs_activate_wait_q, - adapter->hs_activate_wait_q_woken); + adapter->hs_activate_wait_q_woken); return true; } @@ -453,8 +462,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, info->bss_mode = priv->bss_mode; - memcpy(&info->ssid, &bss_desc->ssid, - sizeof(struct mwifiex_802_11_ssid)); + memcpy(&info->ssid, &bss_desc->ssid, sizeof(struct cfg80211_ssid)); memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN); @@ -471,7 +479,7 @@ int mwifiex_get_bss_info(struct mwifiex_private *priv, info->bcn_nf_last = priv->bcn_nf_last; - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + if (priv->sec_info.wep_enabled) info->wep_status = true; else info->wep_status = false; @@ -519,30 +527,27 @@ int mwifiex_bss_set_channel(struct mwifiex_private *priv, adapter->adhoc_start_band = BAND_G | BAND_B; if (chan->channel) { if (chan->channel <= MAX_CHANNEL_BAND_BG) - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, 0, (u16) chan->channel); + cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); if (!cfp) { - cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211 - (priv, BAND_A, (u16) chan->channel); + cfp = mwifiex_get_cfp(priv, BAND_A, + (u16) chan->channel, 0); if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A - | BAND_AN; + | BAND_AN; else adapter->adhoc_start_band = BAND_A; } } } else { if (chan->freq <= MAX_FREQUENCY_BAND_BG) - cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211( - priv, 0, chan->freq); + cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); if (!cfp) { - cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211 - (priv, BAND_A, chan->freq); + cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); if (cfp) { if (adapter->adhoc_11n_enabled) adapter->adhoc_start_band = BAND_A - | BAND_AN; + | BAND_AN; else adapter->adhoc_start_band = BAND_A; } @@ -578,7 +583,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, } return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, - action, 0, channel); + action, 0, channel); } /* @@ -599,7 +604,7 @@ static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, * - Start/Join the IBSS */ int -mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) +mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) { int ret; struct mwifiex_bss_info bss_info; @@ -624,7 +629,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) goto done; } dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", - curr_chan, channel); + curr_chan, channel); if (!bss_info.media_connected) { ret = 0; @@ -636,7 +641,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, - (u16 *) &channel); + &channel); /* Do specific SSID scanning */ if (mwifiex_request_scan(priv, &bss_info.ssid)) { @@ -646,7 +651,8 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); chan = __ieee80211_get_channel(priv->wdev->wiphy, - ieee80211_channel_to_frequency(channel, band)); + ieee80211_channel_to_frequency(channel, + band)); /* Find the BSS we want using available scan results */ bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, @@ -654,7 +660,7 @@ mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel) WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); if (!bss) wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", - bss_info.bssid); + bss_info.bssid); ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); done: @@ -783,7 +789,9 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, if (!ret) { if (rate->is_rate_auto) rate->rate = mwifiex_index_to_data_rate(priv, - priv->tx_rate, priv->tx_htinfo); + priv->tx_rate, + priv->tx_htinfo + ); else rate->rate = priv->data_rate; } else { @@ -820,16 +828,16 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, if ((dbm < priv->min_tx_power_level) || (dbm > priv->max_tx_power_level)) { dev_err(priv->adapter->dev, "txpower value %d dBm" - " is out of range (%d dBm-%d dBm)\n", - dbm, priv->min_tx_power_level, - priv->max_tx_power_level); + " is out of range (%d dBm-%d dBm)\n", + dbm, priv->min_tx_power_level, + priv->max_tx_power_level); return -1; } } buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL); if (!buf) { dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n", - __func__); + __func__); return -ENOMEM; } @@ -837,13 +845,13 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET); if (!power_cfg->is_power_auto) { txp_cfg->mode = cpu_to_le32(1); - pg_tlv = (struct mwifiex_types_power_group *) (buf + - sizeof(struct host_cmd_ds_txpwr_cfg)); + pg_tlv = (struct mwifiex_types_power_group *) + (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); pg_tlv->type = TLV_TYPE_POWER_GROUP; pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); - pg = (struct mwifiex_power_group *) (buf + - sizeof(struct host_cmd_ds_txpwr_cfg) + - sizeof(struct mwifiex_types_power_group)); + pg = (struct mwifiex_power_group *) + (buf + sizeof(struct host_cmd_ds_txpwr_cfg) + + sizeof(struct mwifiex_types_power_group)); /* Power group for modulation class HR/DSSS */ pg->first_rate_code = 0x00; pg->last_rate_code = 0x03; @@ -906,8 +914,8 @@ int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode) sub_cmd, BITMAP_STA_PS, NULL); if ((!ret) && (sub_cmd == DIS_AUTO_PS)) ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS, - 0, NULL); + HostCmd_CMD_802_11_PS_MODE_ENH, + GET_PS, 0, NULL); return ret; } @@ -931,7 +939,7 @@ static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv, memcpy(priv->wpa_ie, ie_data_ptr, ie_len); priv->wpa_ie_len = (u8) ie_len; dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n", - priv->wpa_ie_len, priv->wpa_ie[0]); + priv->wpa_ie_len, priv->wpa_ie[0]); if (priv->wpa_ie[0] == WLAN_EID_WPA) { priv->sec_info.wpa_enabled = true; @@ -972,7 +980,7 @@ static int mwifiex_set_wapi_ie(struct mwifiex_private *priv, memcpy(priv->wapi_ie, ie_data_ptr, ie_len); priv->wapi_ie_len = ie_len; dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n", - priv->wapi_ie_len, priv->wapi_ie[0]); + priv->wapi_ie_len, priv->wapi_ie[0]); if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY) priv->sec_info.wapi_enabled = true; @@ -998,8 +1006,8 @@ static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv, { return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, + encrypt_key); } /* @@ -1020,7 +1028,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, wep_key = &priv->wep_key[priv->wep_key_curr_index]; index = encrypt_key->key_index; if (encrypt_key->key_disable) { - priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED; + priv->sec_info.wep_enabled = 0; } else if (!encrypt_key->key_len) { /* Copy the required key as the current key */ wep_key = &priv->wep_key[index]; @@ -1030,7 +1038,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, return -1; } priv->wep_key_curr_index = (u16) index; - priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; + priv->sec_info.wep_enabled = 1; } else { wep_key = &priv->wep_key[index]; memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); @@ -1040,7 +1048,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, encrypt_key->key_len); wep_key->key_index = index; wep_key->key_length = encrypt_key->key_len; - priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED; + priv->sec_info.wep_enabled = 1; } if (wep_key->key_length) { /* Send request to firmware */ @@ -1050,7 +1058,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv, if (ret) return ret; } - if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED) + if (priv->sec_info.wep_enabled) priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; else priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; @@ -1093,9 +1101,9 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, /* Send the key as PTK to firmware */ encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST; ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + KEY_INFO_ENABLED, encrypt_key); if (ret) return ret; @@ -1120,14 +1128,14 @@ static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv, if (remove_key) ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED), - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + !KEY_INFO_ENABLED, encrypt_key); else ret = mwifiex_send_cmd_sync(priv, - HostCmd_CMD_802_11_KEY_MATERIAL, - HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED, - encrypt_key); + HostCmd_CMD_802_11_KEY_MATERIAL, + HostCmd_ACT_GEN_SET, + KEY_INFO_ENABLED, encrypt_key); return ret; } @@ -1246,7 +1254,7 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv) memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext)); if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT, - HostCmd_ACT_GEN_GET, 0, &ver_ext)) + HostCmd_ACT_GEN_GET, 0, &ver_ext)) return -1; return 0; @@ -1263,7 +1271,7 @@ mwifiex_get_stats_info(struct mwifiex_private *priv, struct mwifiex_ds_get_stats *log) { return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG, - HostCmd_ACT_GEN_GET, 0, log); + HostCmd_ACT_GEN_GET, 0, log); } /* @@ -1403,9 +1411,9 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, } pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; /* Test to see if it is a WPA IE, if not, then it is a gen IE */ - if (((pvendor_ie->element_id == WLAN_EID_WPA) - && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) - || (pvendor_ie->element_id == WLAN_EID_RSN)) { + if (((pvendor_ie->element_id == WLAN_EID_WPA) && + (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui)))) || + (pvendor_ie->element_id == WLAN_EID_RSN)) { /* IE is a WPA/WPA2 IE so call set_wpa function */ ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len); @@ -1428,9 +1436,8 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, * wps session flag */ pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr; - if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) - && (!memcmp(pvendor_ie->oui, wps_oui, - sizeof(wps_oui)))) { + if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC) && + (!memcmp(pvendor_ie->oui, wps_oui, sizeof(wps_oui)))) { priv->wps.session_enable = true; dev_dbg(priv->adapter->dev, "info: WPS Session Enabled.\n"); @@ -1439,7 +1446,7 @@ mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr, /* Append the passed data to the end of the genIeBuffer */ memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr, - ie_len); + ie_len); /* Increment the stored buffer length by the size passed */ priv->gen_ie_buf_len += ie_len; @@ -1483,7 +1490,7 @@ static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv, return -1; } else { memcpy(adapter->arp_filter, gen_ie->ie_data, - gen_ie->len); + gen_ie->len); adapter->arp_filter_size = gen_ie->len; } break; diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 5e1ef7e5da4..750b695aca1 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -43,7 +43,9 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, { int ret; struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); - struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; @@ -124,7 +126,9 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, struct rx_packet_hdr *rx_pkt_hdr; u8 ta[ETH_ALEN]; u16 rx_pkt_type; - struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct mwifiex_private *priv = + mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); if (!priv) return -1; @@ -155,7 +159,7 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, skb_trim(skb, local_rx_pd->rx_pkt_length); ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, - priv->wdev->iftype, 0, false); + priv->wdev->iftype, 0, false); while (!skb_queue_empty(&list)) { rx_skb = __skb_dequeue(&list); diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index d97facd70e8..7af534feb42 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -50,8 +50,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, u8 pad; if (!skb->len) { - dev_err(adapter->dev, "Tx: bad packet length: %d\n", - skb->len); + dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); tx_info->status_code = -1; return skb->data; } @@ -60,19 +59,20 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4; BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN - + pad)); + + pad)); skb_push(skb, sizeof(*local_tx_pd) + pad); local_tx_pd = (struct txpd *) skb->data; memset(local_tx_pd, 0, sizeof(struct txpd)); local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_type = priv->bss_type; - local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len - - (sizeof(struct txpd) + pad))); + local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len - + (sizeof(struct txpd) + + pad))); local_tx_pd->priority = (u8) skb->priority; local_tx_pd->pkt_delay_2ms = - mwifiex_wmm_compute_drv_pkt_delay(priv, skb); + mwifiex_wmm_compute_drv_pkt_delay(priv, skb); if (local_tx_pd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl)) @@ -82,7 +82,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, */ local_tx_pd->tx_control = cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd-> - priority]); + priority]); if (adapter->pps_uapsd_mode) { if (mwifiex_check_last_packet_indication(priv)) { @@ -136,7 +136,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) return -1; tx_info = MWIFIEX_SKB_TXCB(skb); - tx_info->bss_index = priv->bss_index; + tx_info->bss_num = priv->bss_num; + tx_info->bss_type = priv->bss_type; skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN); skb_push(skb, sizeof(struct txpd)); @@ -159,13 +160,13 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) case -1: dev_kfree_skb_any(skb); dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", - __func__, ret); + __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; break; case 0: dev_kfree_skb_any(skb); dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n", - __func__); + __func__); adapter->tx_lock_flag = true; break; case -EINPROGRESS: @@ -191,8 +192,8 @@ mwifiex_check_last_packet_indication(struct mwifiex_private *priv) if (mwifiex_wmm_lists_empty(adapter)) ret = true; - if (ret && !adapter->cmd_sent && !adapter->curr_cmd - && !is_command_pending(adapter)) { + if (ret && !adapter->cmd_sent && !adapter->curr_cmd && + !is_command_pending(adapter)) { adapter->delay_null_pkt = false; ret = true; } else { diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index d9274a1b77a..d2af8cb9854 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -48,7 +48,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - rx_info->bss_index = priv->bss_index; + rx_info->bss_num = priv->bss_num; + rx_info->bss_type = priv->bss_type; return mwifiex_process_sta_rx_packet(adapter, skb); } @@ -84,8 +85,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, switch (ret) { case -EBUSY: if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && - (adapter->pps_uapsd_mode) && - (adapter->tx_lock_flag)) { + (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) { priv->adapter->tx_lock_flag = false; if (local_tx_pd) local_tx_pd->flags = 0; @@ -95,7 +95,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, case -1: adapter->data_sent = false; dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", - ret); + ret); adapter->dbg.num_tx_host_to_card_failure++; mwifiex_write_data_complete(adapter, skb, ret); break; @@ -130,7 +130,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, return 0; tx_info = MWIFIEX_SKB_TXCB(skb); - priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index); + priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, + tx_info->bss_type); if (!priv) goto done; @@ -149,11 +150,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, tpriv = adapter->priv[i]; - if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) - && (tpriv->media_connected)) { + if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && + (tpriv->media_connected)) { if (netif_queue_stopped(tpriv->netdev)) mwifiex_wake_up_net_dev_queue(tpriv->netdev, - adapter); + adapter); } } done: diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 06976f517f6..6b399976d6c 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -93,10 +93,10 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, sizeof(priv->wmm.packets_out)); info->max_tx_buf_size = (u32) adapter->max_tx_buf_size; info->tx_buf_size = (u32) adapter->tx_buf_size; - info->rx_tbl_num = mwifiex_get_rx_reorder_tbl( - priv, info->rx_tbl); - info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl( - priv, info->tx_tbl); + info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(priv, + info->rx_tbl); + info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv, + info->tx_tbl); info->ps_mode = adapter->ps_mode; info->ps_state = adapter->ps_state; info->is_deep_sleep = adapter->is_deep_sleep; @@ -105,19 +105,19 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv, info->is_hs_configured = adapter->is_hs_configured; info->hs_activated = adapter->hs_activated; info->num_cmd_host_to_card_failure - = adapter->dbg.num_cmd_host_to_card_failure; + = adapter->dbg.num_cmd_host_to_card_failure; info->num_cmd_sleep_cfm_host_to_card_failure = adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure; info->num_tx_host_to_card_failure - = adapter->dbg.num_tx_host_to_card_failure; + = adapter->dbg.num_tx_host_to_card_failure; info->num_event_deauth = adapter->dbg.num_event_deauth; info->num_event_disassoc = adapter->dbg.num_event_disassoc; info->num_event_link_lost = adapter->dbg.num_event_link_lost; info->num_cmd_deauth = adapter->dbg.num_cmd_deauth; info->num_cmd_assoc_success = - adapter->dbg.num_cmd_assoc_success; + adapter->dbg.num_cmd_assoc_success; info->num_cmd_assoc_failure = - adapter->dbg.num_cmd_assoc_failure; + adapter->dbg.num_cmd_assoc_failure; info->num_tx_timeout = adapter->dbg.num_tx_timeout; info->num_cmd_timeout = adapter->dbg.num_cmd_timeout; info->timeout_cmd_id = adapter->dbg.timeout_cmd_id; @@ -159,7 +159,8 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) return -1; rx_info = MWIFIEX_SKB_RXCB(skb); - priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); + priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); if (!priv) return -1; @@ -190,7 +191,7 @@ int mwifiex_complete_cmd(struct mwifiex_adapter *adapter, { atomic_dec(&adapter->cmd_pending); dev_dbg(adapter->dev, "cmd completed: status=%d\n", - adapter->cmd_wait_q.status); + adapter->cmd_wait_q.status); *(cmd_node->condition) = true; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 6c239c3c824..5a7316c6f12 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -87,15 +87,15 @@ mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param) const char *ac_str[] = { "BK", "BE", "VI", "VO" }; pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, " - "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", - ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap - & MWIFIEX_ACI) >> 5]], - (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, - (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, - ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, - ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, - (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, - le16_to_cpu(ac_param->tx_op_limit)); + "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n", + ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap + & MWIFIEX_ACI) >> 5]], + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5, + (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4, + ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN, + ac_param->ecw_bitmap & MWIFIEX_ECW_MIN, + (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4, + le16_to_cpu(ac_param->tx_op_limit)); } /* @@ -112,7 +112,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) if (!ra_list) { dev_err(adapter->dev, "%s: failed to alloc ra_list\n", - __func__); + __func__); return NULL; } INIT_LIST_HEAD(&ra_list->list); @@ -154,7 +154,7 @@ mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra) ra_list, ra_list->is_11n_enabled); list_add_tail(&ra_list->list, - &priv->wmm.tid_tbl_ptr[i].ra_list); + &priv->wmm.tid_tbl_ptr[i].ra_list); if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr) priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list; @@ -217,22 +217,19 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, wmm_ie->reserved); for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) { - cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap & - MWIFIEX_ECW_MIN)) - 1; - avg_back_off = (cw_min >> 1) + - (wmm_ie->ac_params[num_ac].aci_aifsn_bitmap & - MWIFIEX_AIFSN); - - ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac]. - aci_aifsn_bitmap & - MWIFIEX_ACI) >> 5]; + u8 ecw = wmm_ie->ac_params[num_ac].ecw_bitmap; + u8 aci_aifsn = wmm_ie->ac_params[num_ac].aci_aifsn_bitmap; + cw_min = (1 << (ecw & MWIFIEX_ECW_MIN)) - 1; + avg_back_off = (cw_min >> 1) + (aci_aifsn & MWIFIEX_AIFSN); + + ac_idx = wmm_aci_to_qidx_map[(aci_aifsn & MWIFIEX_ACI) >> 5]; priv->wmm.queue_priority[ac_idx] = ac_idx; tmp[ac_idx] = avg_back_off; - dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", - (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap & - MWIFIEX_ECW_MAX) >> 4)) - 1, - cw_min, avg_back_off); + dev_dbg(priv->adapter->dev, + "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n", + (1 << ((ecw & MWIFIEX_ECW_MAX) >> 4)) - 1, + cw_min, avg_back_off); mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]); } @@ -312,13 +309,14 @@ mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv) /* WMM is not enabled, default priorities */ for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) priv->wmm.ac_down_graded_vals[ac_val] = - (enum mwifiex_wmm_ac_e) ac_val; + (enum mwifiex_wmm_ac_e) ac_val; } else { for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) { priv->wmm.ac_down_graded_vals[ac_val] = mwifiex_wmm_eval_downgrade_ac(priv, (enum mwifiex_wmm_ac_e) ac_val); - dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n", + dev_dbg(priv->adapter->dev, + "info: WMM: AC PRIO %d maps to %d\n", ac_val, priv->wmm.ac_down_graded_vals[ac_val]); } } @@ -394,13 +392,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) } priv->aggr_prio_tbl[6].amsdu - = priv->aggr_prio_tbl[6].ampdu_ap - = priv->aggr_prio_tbl[6].ampdu_user - = BA_STREAM_NOT_ALLOWED; + = priv->aggr_prio_tbl[6].ampdu_ap + = priv->aggr_prio_tbl[6].ampdu_user + = BA_STREAM_NOT_ALLOWED; priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap - = priv->aggr_prio_tbl[7].ampdu_user - = BA_STREAM_NOT_ALLOWED; + = priv->aggr_prio_tbl[7].ampdu_user + = BA_STREAM_NOT_ALLOWED; priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; @@ -472,7 +470,7 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; i++) mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. - ra_list); + ra_list); atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); @@ -488,9 +486,10 @@ static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv) for (i = 0; i < MAX_NUM_TID; ++i) { dev_dbg(priv->adapter->dev, - "info: ra_list: freeing buf for tid %d\n", i); + "info: ra_list: freeing buf for tid %d\n", i); list_for_each_entry_safe(ra_list, tmp_node, - &priv->wmm.tid_tbl_ptr[i].ra_list, list) { + &priv->wmm.tid_tbl_ptr[i].ra_list, + list) { list_del(&ra_list->list); kfree(ra_list); } @@ -599,11 +598,10 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv, * is queued at the list tail. */ void -mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, +mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, struct sk_buff *skb) { - struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); - struct mwifiex_private *priv = adapter->priv[tx_info->bss_index]; + struct mwifiex_adapter *adapter = priv->adapter; u32 tid; struct mwifiex_ra_list_tbl *ra_list; u8 ra[ETH_ALEN], tid_down; @@ -653,7 +651,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, if (atomic_read(&priv->wmm.highest_queued_prio) < tos_to_tid_inv[tid_down]) atomic_set(&priv->wmm.highest_queued_prio, - tos_to_tid_inv[tid_down]); + tos_to_tid_inv[tid_down]); spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } @@ -682,7 +680,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, struct mwifiex_wmm_ac_status *ac_status; dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n", - resp_len); + resp_len); while ((resp_len >= sizeof(tlv_hdr->header)) && valid) { tlv_hdr = (struct mwifiex_ie_types_data *) curr; @@ -696,15 +694,15 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: CMD_RESP: WMM_GET_STATUS:" " QSTATUS TLV: %d, %d, %d\n", - tlv_wmm_qstatus->queue_index, - tlv_wmm_qstatus->flow_required, - tlv_wmm_qstatus->disabled); + tlv_wmm_qstatus->queue_index, + tlv_wmm_qstatus->flow_required, + tlv_wmm_qstatus->disabled); ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus-> queue_index]; ac_status->disabled = tlv_wmm_qstatus->disabled; ac_status->flow_required = - tlv_wmm_qstatus->flow_required; + tlv_wmm_qstatus->flow_required; ac_status->flow_created = tlv_wmm_qstatus->flow_created; break; @@ -773,29 +771,27 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, if (!wmm_ie) return 0; - dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:" - "bss->wmmIe=0x%x\n", - wmm_ie->vend_hdr.element_id); + dev_dbg(priv->adapter->dev, + "info: WMM: process assoc req: bss->wmm_ie=%#x\n", + wmm_ie->vend_hdr.element_id); - if ((priv->wmm_required - || (ht_cap && (priv->adapter->config_bands & BAND_GN - || priv->adapter->config_bands & BAND_AN)) - ) - && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { + if ((priv->wmm_required || + (ht_cap && (priv->adapter->config_bands & BAND_GN || + priv->adapter->config_bands & BAND_AN))) && + wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) { wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf; wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]); wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]); memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2], - le16_to_cpu(wmm_tlv->header.len)); + le16_to_cpu(wmm_tlv->header.len)); if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) memcpy((u8 *) (wmm_tlv->wmm_ie - + le16_to_cpu(wmm_tlv->header.len) - - sizeof(priv->wmm_qosinfo)), - &priv->wmm_qosinfo, - sizeof(priv->wmm_qosinfo)); + + le16_to_cpu(wmm_tlv->header.len) + - sizeof(priv->wmm_qosinfo)), + &priv->wmm_qosinfo, sizeof(priv->wmm_qosinfo)); ret_len = sizeof(wmm_tlv->header) - + le16_to_cpu(wmm_tlv->header.len); + + le16_to_cpu(wmm_tlv->header.len); *assoc_buf += ret_len; } @@ -814,7 +810,7 @@ mwifiex_wmm_process_association_req(struct mwifiex_private *priv, */ u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, - const struct sk_buff *skb) + const struct sk_buff *skb) { u8 ret_val; struct timeval out_tstamp, in_tstamp; @@ -851,17 +847,18 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, struct mwifiex_ra_list_tbl *ptr, *head; struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head; struct mwifiex_tid_tbl *tid_ptr; + atomic_t *hqp; int is_list_empty; unsigned long flags; int i, j; for (j = adapter->priv_num - 1; j >= 0; --j) { spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); + flags); is_list_empty = list_empty(&adapter->bss_prio_tbl[j] - .bss_prio_head); + .bss_prio_head); spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock, - flags); + flags); if (is_list_empty) continue; @@ -880,12 +877,8 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } do { - atomic_t *hqp; - spinlock_t *lock; - priv_tmp = bssprio_node->priv; hqp = &priv_tmp->wmm.highest_queued_prio; - lock = &priv_tmp->wmm.ra_list_spinlock; for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) { @@ -924,16 +917,10 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, do { is_list_empty = skb_queue_empty(&ptr->skb_head); - if (!is_list_empty) { - spin_lock_irqsave(lock, flags); - if (atomic_read(hqp) > i) - atomic_set(hqp, i); - spin_unlock_irqrestore(lock, - flags); - *priv = priv_tmp; - *tid = tos_to_tid[i]; - return ptr; - } + + if (!is_list_empty) + goto found; + /* Get next ra */ ptr = list_first_entry(&ptr->list, struct mwifiex_ra_list_tbl, @@ -970,6 +957,17 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, } while (bssprio_node != bssprio_head); } return NULL; + +found: + spin_lock_irqsave(&priv_tmp->wmm.ra_list_spinlock, flags); + if (atomic_read(hqp) > i) + atomic_set(hqp, i); + spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags); + + *priv = priv_tmp; + *tid = tos_to_tid[i]; + + return ptr; } /* @@ -1209,25 +1207,24 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) return 0; } - if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) - || ((priv->sec_info.wpa_enabled - || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set) - ) { + if (!ptr->is_11n_enabled || + mwifiex_is_ba_stream_setup(priv, ptr, tid) || + ((priv->sec_info.wpa_enabled || + priv->sec_info.wpa2_enabled) && + !priv->wpa_is_gtk_set)) { mwifiex_send_single_packet(priv, ptr, ptr_index, flags); /* ra_list_spinlock has been freed in mwifiex_send_single_packet() */ } else { if (mwifiex_is_ampdu_allowed(priv, tid)) { if (mwifiex_space_avail_for_new_ba_stream(adapter)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - ptr->ra, tid, - BA_STREAM_SETUP_INPROGRESS); + mwifiex_create_ba_tbl(priv, ptr->ra, tid, + BA_SETUP_INPROGRESS); mwifiex_send_addba(priv, tid, ptr->ra); } else if (mwifiex_find_stream_to_delete (priv, tid, &tid_del, ra)) { - mwifiex_11n_create_tx_ba_stream_tbl(priv, - ptr->ra, tid, - BA_STREAM_SETUP_INPROGRESS); + mwifiex_create_ba_tbl(priv, ptr->ra, tid, + BA_SETUP_INPROGRESS); mwifiex_send_delba(priv, tid_del, ra, 1); } } diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index fcea1f68792..ec839952d2e 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -80,8 +80,8 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) return true; } -void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, - struct sk_buff *skb); +void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, + struct sk_buff *skb); void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index dd5aeaff44b..b48674b577e 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -402,6 +402,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { #define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */ #define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 #define MWL8K_CMD_GET_WATCHDOG_BITMAP 0x0205 +#define MWL8K_CMD_DEL_MAC_ADDR 0x0206 /* per-vif */ #define MWL8K_CMD_BSS_START 0x1100 /* per-vif */ #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ @@ -1330,7 +1331,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit) wh->addr1); if (mwl8k_vif != NULL && - mwl8k_vif->is_hw_crypto_enabled == true) { + mwl8k_vif->is_hw_crypto_enabled) { /* * When MMIC ERROR is encountered * by the firmware, payload is @@ -1993,8 +1994,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb) */ if (txq->len >= MWL8K_TX_DESCS - 2) { - if (mgmtframe == false || - txq->len == MWL8K_TX_DESCS) { + if (!mgmtframe || txq->len == MWL8K_TX_DESCS) { if (start_ba_session) { spin_lock(&priv->stream_lock); mwl8k_remove_stream(hw, stream); @@ -3430,10 +3430,7 @@ static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable) return rc; } -/* - * CMD_SET_MAC_ADDR. - */ -struct mwl8k_cmd_set_mac_addr { +struct mwl8k_cmd_update_mac_addr { struct mwl8k_cmd_pkt header; union { struct { @@ -3449,12 +3446,12 @@ struct mwl8k_cmd_set_mac_addr { #define MWL8K_MAC_TYPE_PRIMARY_AP 2 #define MWL8K_MAC_TYPE_SECONDARY_AP 3 -static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u8 *mac) +static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *mac, bool set) { struct mwl8k_priv *priv = hw->priv; struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); - struct mwl8k_cmd_set_mac_addr *cmd; + struct mwl8k_cmd_update_mac_addr *cmd; int mac_type; int rc; @@ -3475,7 +3472,11 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, if (cmd == NULL) return -ENOMEM; - cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); + if (set) + cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); + else + cmd->header.code = cpu_to_le16(MWL8K_CMD_DEL_MAC_ADDR); + cmd->header.length = cpu_to_le16(sizeof(*cmd)); if (priv->ap_fw) { cmd->mbss.mac_type = cpu_to_le16(mac_type); @@ -3491,6 +3492,24 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, } /* + * MWL8K_CMD_SET_MAC_ADDR. + */ +static inline int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *mac) +{ + return mwl8k_cmd_update_mac_addr(hw, vif, mac, true); +} + +/* + * MWL8K_CMD_DEL_MAC_ADDR. + */ +static inline int mwl8k_cmd_del_mac_addr(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u8 *mac) +{ + return mwl8k_cmd_update_mac_addr(hw, vif, mac, false); +} + +/* * CMD_SET_RATEADAPT_MODE. */ struct mwl8k_cmd_set_rate_adapt_mode { @@ -4093,7 +4112,7 @@ static int mwl8k_set_key(struct ieee80211_hw *hw, return -EOPNOTSUPP; if (sta == NULL) - addr = hw->wiphy->perm_addr; + addr = vif->addr; else addr = sta->addr; @@ -4542,7 +4561,7 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw, if (priv->ap_fw) mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr); - mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00"); + mwl8k_cmd_del_mac_addr(hw, vif, vif->addr); mwl8k_remove_vif(priv, mwl8k_vif); } diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 9fb77d0319f..dd6c64ac406 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -941,11 +941,9 @@ void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw) /* Add desc and skb to rx queue */ rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC); - if (!rx_data) { - printk(KERN_WARNING "%s: Can't allocate RX packet\n", - dev->name); + if (!rx_data) goto drop; - } + rx_data->desc = desc; rx_data->skb = skb; list_add_tail(&rx_data->list, &priv->rx_list); diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index ae8ce56670b..f634d4582bf 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -1754,11 +1754,6 @@ static struct usb_driver orinoco_driver = { .id_table = ezusb_table, }; -/* Can't be declared "const" or the whole __initdata section will - * become const */ -static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION - " (Manuel Estrada Sainz)"; - module_usb_driver(orinoco_driver); MODULE_AUTHOR("Manuel Estrada Sainz"); diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index af2ca1a9c7d..ee8af1f047c 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -227,6 +227,9 @@ static int p54_add_interface(struct ieee80211_hw *dev, struct ieee80211_vif *vif) { struct p54_common *priv = dev->priv; + int err; + + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; mutex_lock(&priv->conf_mutex); if (priv->mode != NL80211_IFTYPE_MONITOR) { @@ -249,9 +252,9 @@ static int p54_add_interface(struct ieee80211_hw *dev, } memcpy(priv->mac_addr, vif->addr, ETH_ALEN); - p54_setup_mac(priv); + err = p54_setup_mac(priv); mutex_unlock(&priv->conf_mutex); - return 0; + return err; } static void p54_remove_interface(struct ieee80211_hw *dev, @@ -734,7 +737,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_REPORTS_TX_ACK_STATUS; dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index b1f51a21579..45df728183f 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -624,36 +624,39 @@ static void __devexit p54p_remove(struct pci_dev *pdev) } #ifdef CONFIG_PM -static int p54p_suspend(struct pci_dev *pdev, pm_message_t state) +static int p54p_suspend(struct device *device) { - struct ieee80211_hw *dev = pci_get_drvdata(pdev); - struct p54p_priv *priv = dev->priv; - - if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { - ieee80211_stop_queues(dev); - p54p_stop(dev); - } + struct pci_dev *pdev = to_pci_dev(device); pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); + pci_set_power_state(pdev, PCI_D3hot); + pci_disable_device(pdev); return 0; } -static int p54p_resume(struct pci_dev *pdev) +static int p54p_resume(struct device *device) { - struct ieee80211_hw *dev = pci_get_drvdata(pdev); - struct p54p_priv *priv = dev->priv; + struct pci_dev *pdev = to_pci_dev(device); + int err; - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); + err = pci_reenable_device(pdev); + if (err) + return err; + return pci_set_power_state(pdev, PCI_D0); +} - if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED) { - p54p_open(dev); - ieee80211_wake_queues(dev); - } +static const struct dev_pm_ops p54pci_pm_ops = { + .suspend = p54p_suspend, + .resume = p54p_resume, + .freeze = p54p_suspend, + .thaw = p54p_resume, + .poweroff = p54p_suspend, + .restore = p54p_resume, +}; - return 0; -} +#define P54P_PM_OPS (&p54pci_pm_ops) +#else +#define P54P_PM_OPS (NULL) #endif /* CONFIG_PM */ static struct pci_driver p54p_driver = { @@ -661,10 +664,7 @@ static struct pci_driver p54p_driver = { .id_table = p54p_table, .probe = p54p_probe, .remove = __devexit_p(p54p_remove), -#ifdef CONFIG_PM - .suspend = p54p_suspend, - .resume = p54p_resume, -#endif /* CONFIG_PM */ + .driver.pm = P54P_PM_OPS, }; static int __init p54p_init(void) diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 7faed62c637..f7929906d43 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -618,19 +618,19 @@ static int __devinit p54spi_probe(struct spi_device *spi) ret = spi_setup(spi); if (ret < 0) { dev_err(&priv->spi->dev, "spi_setup failed"); - goto err_free_common; + goto err_free; } ret = gpio_request(p54spi_gpio_power, "p54spi power"); if (ret < 0) { dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); - goto err_free_common; + goto err_free; } ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); if (ret < 0) { dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); - goto err_free_common; + goto err_free_gpio_power; } gpio_direction_output(p54spi_gpio_power, 0); @@ -641,7 +641,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); - goto err_free_common; + goto err_free_gpio_irq; } irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); @@ -673,6 +673,12 @@ static int __devinit p54spi_probe(struct spi_device *spi) return 0; err_free_common: + free_irq(gpio_to_irq(p54spi_gpio_irq), spi); +err_free_gpio_irq: + gpio_free(p54spi_gpio_irq); +err_free_gpio_power: + gpio_free(p54spi_gpio_power); +err_free: p54_free_common(priv->hw); return ret; } diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 42b97bc3847..a08a6f0e4dd 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -690,7 +690,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb, if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR; - if (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE) + if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index a5224f6160e..851fa10241e 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -192,11 +192,9 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid, err = -ENOMEM; p = buf.mem = kmalloc(frag_len, GFP_KERNEL); - if (!buf.mem) { - printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n", - ndev->name); + if (!buf.mem) goto error; - } + buf.size = frag_len; /* create the header directly in the fragment data area */ diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index a330c69583d..d66e2980bc2 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -518,7 +518,7 @@ struct rndis_wlan_private { __le32 current_command_oid; /* encryption stuff */ - int encr_tx_key_index; + u8 encr_tx_key_index; struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; int wpa_version; @@ -634,7 +634,7 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv) } } -static bool is_wpa_key(struct rndis_wlan_private *priv, int idx) +static bool is_wpa_key(struct rndis_wlan_private *priv, u8 idx) { int cipher = priv->encr_keys[idx].cipher; @@ -1350,7 +1350,7 @@ static int set_channel(struct usbnet *usbdev, int channel) } static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, - u16 *beacon_interval) + u32 *beacon_period) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ieee80211_channel *channel; @@ -1370,14 +1370,14 @@ static struct ieee80211_channel *get_current_channel(struct usbnet *usbdev, if (!channel) return NULL; - if (beacon_interval) - *beacon_interval = le16_to_cpu(config.beacon_period); + if (beacon_period) + *beacon_period = le32_to_cpu(config.beacon_period); return channel; } /* index must be 0 - N, as per NDIS */ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, - int index) + u8 index) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ndis_80211_wep_key ndis_key; @@ -1387,13 +1387,15 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, netdev_dbg(usbdev->net, "%s(idx: %d, len: %d)\n", __func__, index, key_len); - if ((key_len != 5 && key_len != 13) || index < 0 || index > 3) + if (index >= RNDIS_WLAN_NUM_KEYS) return -EINVAL; if (key_len == 5) cipher = WLAN_CIPHER_SUITE_WEP40; - else + else if (key_len == 13) cipher = WLAN_CIPHER_SUITE_WEP104; + else + return -EINVAL; memset(&ndis_key, 0, sizeof(ndis_key)); @@ -1428,7 +1430,7 @@ static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len, } static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, - int index, const u8 *addr, const u8 *rx_seq, + u8 index, const u8 *addr, const u8 *rx_seq, int seq_len, u32 cipher, __le32 flags) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); @@ -1436,7 +1438,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, bool is_addr_ok; int ret; - if (index < 0 || index >= 4) { + if (index >= RNDIS_WLAN_NUM_KEYS) { netdev_dbg(usbdev->net, "%s(): index out of range (%i)\n", __func__, index); return -EINVAL; @@ -1524,7 +1526,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, return 0; } -static int restore_key(struct usbnet *usbdev, int key_idx) +static int restore_key(struct usbnet *usbdev, u8 key_idx) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct rndis_wlan_encr_key key; @@ -1550,13 +1552,13 @@ static void restore_keys(struct usbnet *usbdev) restore_key(usbdev, i); } -static void clear_key(struct rndis_wlan_private *priv, int idx) +static void clear_key(struct rndis_wlan_private *priv, u8 idx) { memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx])); } /* remove_key is for both wep and wpa */ -static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) +static int remove_key(struct usbnet *usbdev, u8 index, const u8 *bssid) { struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ndis_80211_remove_key remove_key; @@ -1790,9 +1792,9 @@ static struct ndis_80211_pmkid *remove_pmkid(struct usbnet *usbdev, struct cfg80211_pmksa *pmksa, int max_pmkids) { - int i, len, count, newlen, err; + int i, newlen, err; + unsigned int count; - len = le32_to_cpu(pmkids->length); count = le32_to_cpu(pmkids->bssid_info_count); if (count > max_pmkids) @@ -1831,9 +1833,9 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, struct cfg80211_pmksa *pmksa, int max_pmkids) { - int i, err, len, count, newlen; + int i, err, newlen; + unsigned int count; - len = le32_to_cpu(pmkids->length); count = le32_to_cpu(pmkids->bssid_info_count); if (count > max_pmkids) @@ -2683,7 +2685,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, s32 signal; u64 timestamp; u16 capability; - u16 beacon_interval = 0; + u32 beacon_period = 0; __le32 rssi; u8 ie_buf[34]; int len, ret, ie_len; @@ -2708,7 +2710,7 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, } /* Get channel and beacon interval */ - channel = get_current_channel(usbdev, &beacon_interval); + channel = get_current_channel(usbdev, &beacon_period); if (!channel) { netdev_warn(usbdev->net, "%s(): could not get channel.\n", __func__); @@ -2738,11 +2740,11 @@ static void rndis_wlan_craft_connected_bss(struct usbnet *usbdev, u8 *bssid, netdev_dbg(usbdev->net, "%s(): channel:%d(freq), bssid:[%pM], tsf:%d, " "capa:%x, beacon int:%d, resp_ie(len:%d, essid:'%.32s'), " "signal:%d\n", __func__, (channel ? channel->center_freq : -1), - bssid, (u32)timestamp, capability, beacon_interval, ie_len, + bssid, (u32)timestamp, capability, beacon_period, ie_len, ssid.essid, signal); bss = cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid, - timestamp, capability, beacon_interval, ie_buf, ie_len, + timestamp, capability, beacon_period, ie_buf, ie_len, signal, GFP_KERNEL); cfg80211_put_bss(bss); } @@ -2755,9 +2757,10 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); struct ndis_80211_assoc_info *info = NULL; u8 bssid[ETH_ALEN]; - int resp_ie_len, req_ie_len; + unsigned int resp_ie_len, req_ie_len; + unsigned int offset; u8 *req_ie, *resp_ie; - int ret, offset; + int ret; bool roamed = false; bool match_bss; @@ -2785,7 +2788,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) ret = get_association_info(usbdev, info, CONTROL_BUFFER_SIZE); if (!ret) { req_ie_len = le32_to_cpu(info->req_ie_length); - if (req_ie_len > 0) { + if (req_ie_len > CONTROL_BUFFER_SIZE) + req_ie_len = CONTROL_BUFFER_SIZE; + if (req_ie_len != 0) { offset = le32_to_cpu(info->offset_req_ies); if (offset > CONTROL_BUFFER_SIZE) @@ -2799,7 +2804,9 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev) } resp_ie_len = le32_to_cpu(info->resp_ie_length); - if (resp_ie_len > 0) { + if (resp_ie_len > CONTROL_BUFFER_SIZE) + resp_ie_len = CONTROL_BUFFER_SIZE; + if (resp_ie_len != 0) { offset = le32_to_cpu(info->offset_resp_ies); if (offset > CONTROL_BUFFER_SIZE) @@ -3038,7 +3045,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, struct rndis_indicate *msg, int buflen) { struct ndis_80211_status_indication *indication; - int len, offset; + unsigned int len, offset; offset = offsetof(struct rndis_indicate, status) + le32_to_cpu(msg->offset); @@ -3050,7 +3057,7 @@ static void rndis_wlan_media_specific_indication(struct usbnet *usbdev, return; } - if (offset + len > buflen) { + if (len > buflen || offset > buflen || offset + len > buflen) { netdev_info(usbdev->net, "media specific indication, too large to fit to buffer (%i > %i)\n", offset + len, buflen); return; diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index a0a7854facc..299c3879582 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -163,7 +163,7 @@ config RT2800USB_RT53XX depends on EXPERIMENTAL ---help--- This adds support for rt53xx wireless chipset family to the - rt2800pci driver. + rt2800usb driver. Supported chips: RT5370 config RT2800USB_UNKNOWN diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2571a2fa3d0..063bfa8b91f 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -68,6 +68,7 @@ #define RF3322 0x000c #define RF3053 0x000d #define RF5370 0x5370 +#define RF5372 0x5372 #define RF5390 0x5390 /* @@ -965,6 +966,7 @@ * TX_PIN_CFG: */ #define TX_PIN_CFG 0x1328 +#define TX_PIN_CFG_PA_PE_DISABLE 0xfcfffff0 #define TX_PIN_CFG_PA_PE_A0_EN FIELD32(0x00000001) #define TX_PIN_CFG_PA_PE_G0_EN FIELD32(0x00000002) #define TX_PIN_CFG_PA_PE_A1_EN FIELD32(0x00000004) @@ -985,6 +987,14 @@ #define TX_PIN_CFG_RFTR_POL FIELD32(0x00020000) #define TX_PIN_CFG_TRSW_EN FIELD32(0x00040000) #define TX_PIN_CFG_TRSW_POL FIELD32(0x00080000) +#define TX_PIN_CFG_PA_PE_A2_EN FIELD32(0x01000000) +#define TX_PIN_CFG_PA_PE_G2_EN FIELD32(0x02000000) +#define TX_PIN_CFG_PA_PE_A2_POL FIELD32(0x04000000) +#define TX_PIN_CFG_PA_PE_G2_POL FIELD32(0x08000000) +#define TX_PIN_CFG_LNA_PE_A2_EN FIELD32(0x10000000) +#define TX_PIN_CFG_LNA_PE_G2_EN FIELD32(0x20000000) +#define TX_PIN_CFG_LNA_PE_A2_POL FIELD32(0x40000000) +#define TX_PIN_CFG_LNA_PE_G2_POL FIELD32(0x80000000) /* * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz @@ -1627,6 +1637,7 @@ struct mac_iveiv_entry { /* * H2M_MAILBOX_CSR: Host-to-MCU Mailbox. + * CMD_TOKEN: Command id, 0xff disable status reporting. */ #define H2M_MAILBOX_CSR 0x7010 #define H2M_MAILBOX_CSR_ARG0 FIELD32(0x000000ff) @@ -1636,6 +1647,8 @@ struct mac_iveiv_entry { /* * H2M_MAILBOX_CID: + * Free slots contain 0xff. MCU will store command's token to lowest free slot. + * If all slots are occupied status will be dropped. */ #define H2M_MAILBOX_CID 0x7014 #define H2M_MAILBOX_CID_CMD0 FIELD32(0x000000ff) @@ -1645,6 +1658,7 @@ struct mac_iveiv_entry { /* * H2M_MAILBOX_STATUS: + * Command status will be saved to same slot as command id. */ #define H2M_MAILBOX_STATUS 0x701c @@ -1796,6 +1810,14 @@ struct mac_iveiv_entry { #define RFCSR2_RESCAL_EN FIELD8(0x80) /* + * RFCSR 3: + */ +#define RFCSR3_K FIELD8(0x0f) +/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ +#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70); +#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80); + +/* * FRCSR 5: */ #define RFCSR5_R1 FIELD8(0x0c) @@ -1811,10 +1833,12 @@ struct mac_iveiv_entry { * RFCSR 7: */ #define RFCSR7_RF_TUNING FIELD8(0x01) -#define RFCSR7_R02 FIELD8(0x07) -#define RFCSR7_R3 FIELD8(0x08) -#define RFCSR7_R45 FIELD8(0x30) -#define RFCSR7_R67 FIELD8(0xc0) +#define RFCSR7_BIT1 FIELD8(0x02) +#define RFCSR7_BIT2 FIELD8(0x04) +#define RFCSR7_BIT3 FIELD8(0x08) +#define RFCSR7_BIT4 FIELD8(0x10) +#define RFCSR7_BIT5 FIELD8(0x20) +#define RFCSR7_BITS67 FIELD8(0xc0) /* * RFCSR 11: @@ -1839,6 +1863,11 @@ struct mac_iveiv_entry { #define RFCSR15_TX_LO2_EN FIELD8(0x08) /* + * RFCSR 16: + */ +#define RFCSR16_TXMIXER_GAIN FIELD8(0x07) + +/* * RFCSR 17: */ #define RFCSR17_TXMIXER_GAIN FIELD8(0x07) @@ -1867,6 +1896,13 @@ struct mac_iveiv_entry { #define RFCSR23_FREQ_OFFSET FIELD8(0x7f) /* + * RFCSR 24: + */ +#define RFCSR24_TX_AGC_FC FIELD8(0x1f) +#define RFCSR24_TX_H20M FIELD8(0x20) +#define RFCSR24_TX_CALIB FIELD8(0x7f) + +/* * RFCSR 27: */ #define RFCSR27_R1 FIELD8(0x03) @@ -1887,6 +1923,7 @@ struct mac_iveiv_entry { */ #define RFCSR31_RX_AGC_FC FIELD8(0x1f) #define RFCSR31_RX_H20M FIELD8(0x20) +#define RFCSR31_RX_CALIB FIELD8(0x7f) /* * RFCSR 38: @@ -2093,6 +2130,12 @@ struct mac_iveiv_entry { #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) /* + * EEPROM TXMIXER GAIN A offset (note overlaps with EEPROM RSSI A2). + */ +#define EEPROM_TXMIXER_GAIN_A 0x0026 +#define EEPROM_TXMIXER_GAIN_A_VAL FIELD16(0x0007) + +/* * EEPROM EIRP Maximum TX power values(unit: dbm) */ #define EEPROM_EIRP_MAX_TX_POWER 0x0027 @@ -2259,6 +2302,12 @@ struct mac_iveiv_entry { /* * MCU mailbox commands. + * MCU_SLEEP - go to power-save mode. + * arg1: 1: save as much power as possible, 0: save less power. + * status: 1: success, 2: already asleep, + * 3: maybe MAC is busy so can't finish this task. + * MCU_RADIO_OFF + * arg0: 0: do power-saving, NOT turn off radio. */ #define MCU_SLEEP 0x30 #define MCU_WAKEUP 0x31 @@ -2279,7 +2328,10 @@ struct mac_iveiv_entry { /* * MCU mailbox tokens */ -#define TOKEN_WAKUP 3 +#define TOKEN_SLEEP 1 +#define TOKEN_RADIO_OFF 2 +#define TOKEN_WAKEUP 3 + /* * DMA descriptor defines. @@ -2422,4 +2474,23 @@ struct mac_iveiv_entry { */ #define EIRP_MAX_TX_POWER_LIMIT 0x50 +/* + * Number of TBTT intervals after which we have to adjust + * the hw beacon timer. + */ +#define BCN_TBTT_OFFSET 64 + +/* + * RT2800 driver data structure + */ +struct rt2800_drv_data { + u8 calibration_bw20; + u8 calibration_bw40; + u8 bbp25; + u8 bbp26; + u8 txmixer_gain_24g; + u8 txmixer_gain_5g; + unsigned int tbtt_tick; +}; + #endif /* RT2800_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 7bef66def10..6c0a12ea6a1 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -402,7 +402,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, if (rt2x00_is_pci(rt2x00dev)) { if (rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT5390)) { + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_register_read(rt2x00dev, AUX_CTRL, ®); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); @@ -412,18 +413,6 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, } /* - * Disable DMA, will be reenabled later when enabling - * the radio. - */ - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - /* * Write firmware to the device. */ rt2800_drv_write_firmware(rt2x00dev, data, len); @@ -444,10 +433,21 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, } /* + * Disable DMA, will be reenabled later when enabling + * the radio. + */ + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + /* * Initialize firmware. */ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + if (rt2x00_is_usb(rt2x00dev)) + rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); msleep(1); return 0; @@ -1646,10 +1646,14 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, struct rf_channel *rf, struct channel_info *info) { - u8 rfcsr; + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u8 rfcsr, calib_tx, calib_rx; rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); - rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR3_K, rf->rf3); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2); @@ -1663,16 +1667,82 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); + if (rt2x00_rt(rt2x00dev, RT3390)) { + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, + rt2x00dev->default_ant.rx_chain_num == 1); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, + rt2x00dev->default_ant.tx_chain_num == 1); + } else { + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); + + switch (rt2x00dev->default_ant.tx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); + /* fall through */ + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); + break; + } + + switch (rt2x00dev->default_ant.rx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); + /* fall through */ + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); + break; + } + } + rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 24, - rt2x00dev->calibration[conf_is_ht40(conf)]); + if (rt2x00_rt(rt2x00dev, RT3390)) { + calib_tx = conf_is_ht40(conf) ? 0x68 : 0x4f; + calib_rx = conf_is_ht40(conf) ? 0x6f : 0x4f; + } else { + if (conf_is_ht40(conf)) { + calib_tx = drv_data->calibration_bw40; + calib_rx = drv_data->calibration_bw40; + } else { + calib_tx = drv_data->calibration_bw20; + calib_rx = drv_data->calibration_bw20; + } + } + + rt2800_rfcsr_read(rt2x00dev, 24, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR24_TX_CALIB, calib_tx); + rt2800_rfcsr_write(rt2x00dev, 24, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 31, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR31_RX_CALIB, calib_rx); + rt2800_rfcsr_write(rt2x00dev, 31, rfcsr); rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); } static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, @@ -1680,12 +1750,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, struct rf_channel *rf, struct channel_info *info) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u8 rfcsr; u32 reg; if (rf->channel <= 14) { - rt2800_bbp_write(rt2x00dev, 25, 0x15); - rt2800_bbp_write(rt2x00dev, 26, 0x85); + rt2800_bbp_write(rt2x00dev, 25, drv_data->bbp25); + rt2800_bbp_write(rt2x00dev, 26, drv_data->bbp26); } else { rt2800_bbp_write(rt2x00dev, 25, 0x09); rt2800_bbp_write(rt2x00dev, 26, 0xff); @@ -1713,8 +1784,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3); rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, - (info->default_power1 & 0x3) | - ((info->default_power1 & 0xC) << 1)); + info->default_power1); } else { rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7); rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, @@ -1727,8 +1797,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3); rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, - (info->default_power2 & 0x3) | - ((info->default_power2 & 0xC) << 1)); + info->default_power2); } else { rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7); rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, @@ -1738,11 +1807,12 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); @@ -1773,10 +1843,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); - rt2800_rfcsr_write(rt2x00dev, 24, - rt2x00dev->calibration[conf_is_ht40(conf)]); - rt2800_rfcsr_write(rt2x00dev, 31, - rt2x00dev->calibration[conf_is_ht40(conf)]); + if (conf_is_ht40(conf)) { + rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw40); + rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw40); + } else { + rt2800_rfcsr_write(rt2x00dev, 24, drv_data->calibration_bw20); + rt2800_rfcsr_write(rt2x00dev, 31, drv_data->calibration_bw20); + } if (rf->channel <= 14) { rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); @@ -1784,7 +1857,10 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); rt2800_rfcsr_write(rt2x00dev, 15, 0x53); - rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); + rfcsr = 0x4c; + rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN, + drv_data->txmixer_gain_24g); + rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); rt2800_rfcsr_write(rt2x00dev, 17, 0x23); rt2800_rfcsr_write(rt2x00dev, 19, 0x93); rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); @@ -1793,12 +1869,20 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 27, 0x00); rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); } else { - rt2800_rfcsr_write(rt2x00dev, 7, 0x14); + rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR7_BIT2, 1); + rt2x00_set_field8(&rfcsr, RFCSR7_BIT3, 0); + rt2x00_set_field8(&rfcsr, RFCSR7_BIT4, 1); + rt2x00_set_field8(&rfcsr, RFCSR7_BITS67, 0); + rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); rt2800_rfcsr_write(rt2x00dev, 11, 0x00); rt2800_rfcsr_write(rt2x00dev, 15, 0x43); - rt2800_rfcsr_write(rt2x00dev, 16, 0x7a); + rfcsr = 0x7a; + rt2x00_set_field8(&rfcsr, RFCSR16_TXMIXER_GAIN, + drv_data->txmixer_gain_5g); + rt2800_rfcsr_write(rt2x00dev, 16, rfcsr); rt2800_rfcsr_write(rt2x00dev, 17, 0x23); if (rf->channel <= 64) { rt2800_rfcsr_write(rt2x00dev, 19, 0xb7); @@ -1906,7 +1990,8 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, r55_nonbt_rev[idx]); rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]); - } else if (rt2x00_rt(rt2x00dev, RT5390)) { + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { static const char r59_non_bt[] = {0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; @@ -1956,6 +2041,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); break; case RF5370: + case RF5372: case RF5390: rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); break; @@ -1972,7 +2058,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_bbp_write(rt2x00dev, 86, 0); if (rf->channel <= 14) { - if (!rt2x00_rt(rt2x00dev, RT5390)) { + if (!rt2x00_rt(rt2x00dev, RT5390) && + !rt2x00_rt(rt2x00dev, RT5392)) { if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { rt2800_bbp_write(rt2x00dev, 82, 0x62); @@ -2414,6 +2501,80 @@ void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2800_gain_calibration); +void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) +{ + u32 tx_pin; + u8 rfcsr; + + /* + * A voltage-controlled oscillator(VCO) is an electronic oscillator + * designed to be controlled in oscillation frequency by a voltage + * input. Maybe the temperature will affect the frequency of + * oscillation to be shifted. The VCO calibration will be called + * periodically to adjust the frequency to be precision. + */ + + rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); + tx_pin &= TX_PIN_CFG_PA_PE_DISABLE; + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: + case RF3021: + case RF3022: + case RF3320: + case RF3052: + rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); + rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); + break; + case RF5370: + case RF5372: + case RF5390: + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); + break; + default: + return; + } + + mdelay(1); + + rt2800_register_read(rt2x00dev, TX_PIN_CFG, &tx_pin); + if (rt2x00dev->rf_channel <= 14) { + switch (rt2x00dev->default_ant.tx_chain_num) { + case 3: + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN, 1); + /* fall through */ + case 2: + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); + /* fall through */ + case 1: + default: + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); + break; + } + } else { + switch (rt2x00dev->default_ant.tx_chain_num) { + case 3: + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN, 1); + /* fall through */ + case 2: + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); + /* fall through */ + case 1: + default: + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, 1); + break; + } + } + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + +} +EXPORT_SYMBOL_GPL(rt2800_vco_calibration); + static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf) { @@ -2502,7 +2663,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || - rt2x00_rt(rt2x00dev, RT5390)) + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) return 0x1c + (2 * rt2x00dev->lna_gain); else return 0x2e + rt2x00dev->lna_gain; @@ -2637,7 +2799,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) } else if (rt2x00_rt(rt2x00dev, RT3572)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); - } else if (rt2x00_rt(rt2x00dev, RT5390)) { + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); @@ -3013,7 +3176,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2x00_rt(rt2x00dev, RT5390)) { + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_read(rt2x00dev, 4, &value); rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); rt2800_bbp_write(rt2x00dev, 4, value); @@ -3021,19 +3185,22 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2800_is_305x_soc(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT5390)) + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 31, 0x08); rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 68, 0x0b); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { rt2800_bbp_write(rt2x00dev, 69, 0x16); rt2800_bbp_write(rt2x00dev, 73, 0x12); - } else if (rt2x00_rt(rt2x00dev, RT5390)) { + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x13); rt2800_bbp_write(rt2x00dev, 75, 0x46); @@ -3051,7 +3218,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT5390)) { + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_write(rt2x00dev, 79, 0x13); rt2800_bbp_write(rt2x00dev, 80, 0x05); rt2800_bbp_write(rt2x00dev, 81, 0x33); @@ -3063,64 +3231,88 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) } rt2800_bbp_write(rt2x00dev, 82, 0x62); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 83, 0x7a); else rt2800_bbp_write(rt2x00dev, 83, 0x6a); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); - else if (rt2x00_rt(rt2x00dev, RT5390)) + else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 86, 0x38); else rt2800_bbp_write(rt2x00dev, 86, 0x00); + if (rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 88, 0x90); + rt2800_bbp_write(rt2x00dev, 91, 0x04); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 92, 0x02); else rt2800_bbp_write(rt2x00dev, 92, 0x00); + if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_bbp_write(rt2x00dev, 95, 0x9a); + rt2800_bbp_write(rt2x00dev, 98, 0x12); + } + if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 103, 0xc0); else rt2800_bbp_write(rt2x00dev, 103, 0x00); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 104, 0x92); if (rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 105, 0x01); - else if (rt2x00_rt(rt2x00dev, RT5390)) + else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); if (rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 106, 0x03); + else if (rt2x00_rt(rt2x00dev, RT5392)) + rt2800_bbp_write(rt2x00dev, 106, 0x12); else rt2800_bbp_write(rt2x00dev, 106, 0x35); - if (rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 128, 0x12); + if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_bbp_write(rt2x00dev, 134, 0xd0); + rt2800_bbp_write(rt2x00dev, 135, 0xf6); + } + if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT5390)) { + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_read(rt2x00dev, 138, &value); rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); @@ -3132,7 +3324,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } - if (rt2x00_rt(rt2x00dev, RT5390)) { + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { int ant, div_mode; rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); @@ -3247,6 +3440,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u8 rfcsr; u8 bbp; u32 reg; @@ -3258,13 +3452,15 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) !rt2x00_rt(rt2x00dev, RT3390) && !rt2x00_rt(rt2x00dev, RT3572) && !rt2x00_rt(rt2x00dev, RT5390) && + !rt2x00_rt(rt2x00dev, RT5392) && !rt2800_is_305x_soc(rt2x00dev)) return 0; /* * Init RF calibration. */ - if (rt2x00_rt(rt2x00dev, RT5390)) { + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); @@ -3482,6 +3678,66 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); rt2800_rfcsr_write(rt2x00dev, 62, 0x00); rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } else if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x17); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x88); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 24, 0x44); + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x20); + rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x89); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x94); + rt2800_rfcsr_write(rt2x00dev, 50, 0x94); + rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); + rt2800_rfcsr_write(rt2x00dev, 52, 0x48); + rt2800_rfcsr_write(rt2x00dev, 53, 0x44); + rt2800_rfcsr_write(rt2x00dev, 54, 0x38); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); + rt2800_rfcsr_write(rt2x00dev, 57, 0x00); + rt2800_rfcsr_write(rt2x00dev, 58, 0x39); + rt2800_rfcsr_write(rt2x00dev, 59, 0x07); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0x91); + rt2800_rfcsr_write(rt2x00dev, 62, 0x39); + rt2800_rfcsr_write(rt2x00dev, 63, 0x07); } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -3535,21 +3791,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) * Set RX Filter calibration for 20MHz and 40MHz */ if (rt2x00_rt(rt2x00dev, RT3070)) { - rt2x00dev->calibration[0] = + drv_data->calibration_bw20 = rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x16); - rt2x00dev->calibration[1] = + drv_data->calibration_bw40 = rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); } else if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572)) { - rt2x00dev->calibration[0] = + drv_data->calibration_bw20 = rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); - rt2x00dev->calibration[1] = + drv_data->calibration_bw40 = rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); } - if (!rt2x00_rt(rt2x00dev, RT5390)) { + /* + * Save BBP 25 & 26 values for later use in channel switching + */ + rt2800_bbp_read(rt2x00dev, 25, &drv_data->bbp25); + rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); + + if (!rt2x00_rt(rt2x00dev, RT5390) && + !rt2x00_rt(rt2x00dev, RT5392)) { /* * Set back to initial state */ @@ -3577,7 +3840,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); - if (!rt2x00_rt(rt2x00dev, RT5390)) { + if (!rt2x00_rt(rt2x00dev, RT5390) && + !rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); if (rt2x00_rt(rt2x00dev, RT3070) || @@ -3588,11 +3852,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) &rt2x00dev->cap_flags)) rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); } - rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); - if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) - rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, - rt2x00_get_field16(eeprom, - EEPROM_TXMIXER_GAIN_BG_VAL)); + rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, + drv_data->txmixer_gain_24g); rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); } @@ -3645,7 +3906,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); } - if (rt2x00_rt(rt2x00dev, RT5390)) { + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); @@ -3800,6 +4062,7 @@ EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse); int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) { + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; u16 word; u8 *mac; u8 default_lna_gain; @@ -3883,6 +4146,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word); + if ((word & 0x00ff) != 0x00ff) { + drv_data->txmixer_gain_24g = + rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_BG_VAL); + } else { + drv_data->txmixer_gain_24g = 0; + } + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word); if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); @@ -3892,6 +4163,14 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) default_lna_gain); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A, &word); + if ((word & 0x00ff) != 0x00ff) { + drv_data->txmixer_gain_5g = + rt2x00_get_field16(word, EEPROM_TXMIXER_GAIN_A_VAL); + } else { + drv_data->txmixer_gain_5g = 0; + } + rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word); if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10) rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0); @@ -3929,7 +4208,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) * RT53xx: defined in "EEPROM_CHIP_ID" field */ rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) + if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || + rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); else value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); @@ -3947,9 +4227,10 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RT3390: case RT3572: case RT5390: + case RT5392: break; default: - ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); + ERROR(rt2x00dev, "Invalid RT chipset 0x%04x detected.\n", rt2x00dev->chip.rt); return -ENODEV; } @@ -3965,10 +4246,11 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3052: case RF3320: case RF5370: + case RF5372: case RF5390: break; default: - ERROR(rt2x00dev, "Invalid RF chipset 0x%x detected.\n", + ERROR(rt2x00dev, "Invalid RF chipset 0x%04x detected.\n", rt2x00dev->chip.rf); return -ENODEV; } @@ -4218,7 +4500,9 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_AMPDU_AGGREGATION; + IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_REPORTS_TX_ACK_STATUS; + /* * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices * unless we are capable of sending the buffered frames out after the @@ -4271,6 +4555,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF3022) || rt2x00_rf(rt2x00dev, RF3320) || rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || rt2x00_rf(rt2x00dev, RF5390)) { spec->num_channels = 14; spec->channels = rf_vals_3x; @@ -4347,6 +4632,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) } } + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: + case RF3021: + case RF3022: + case RF3320: + case RF3052: + case RF5370: + case RF5372: + case RF5390: + __set_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags); + break; + } + return 0; } EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 8c3c281904f..419e36cb06b 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -184,6 +184,7 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev); +void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev); int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index dc88baefa72..0397bbf0ce0 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -480,7 +480,8 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) if (rt2x00_is_pcie(rt2x00dev) && (rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT5390))) { + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392))) { rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); @@ -489,7 +490,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); @@ -501,11 +502,27 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) { + int retval; + if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || rt2800pci_init_queues(rt2x00dev))) return -EIO; - return rt2800_enable_radio(rt2x00dev); + retval = rt2800_enable_radio(rt2x00dev); + if (retval) + return retval; + + /* After resume MCU_BOOT_SIGNAL will trash these. */ + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); + rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); + + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02); + rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF); + + rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, 0, 0); + rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); + + return retval; } static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) @@ -521,14 +538,16 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { if (state == STATE_AWAKE) { - rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02); - rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP); + rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKEUP, + 0, 0x02); + rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP); } else if (state == STATE_SLEEP) { rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff); rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff); - rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01); + rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP, + 0xff, 0x01); } return 0; @@ -541,13 +560,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, switch (state) { case STATE_RADIO_ON: - /* - * Before the radio can be enabled, the device first has - * to be woken up. After that it needs a bit of time - * to be fully awake and then the radio can be enabled. - */ - rt2800pci_set_state(rt2x00dev, STATE_AWAKE); - msleep(1); retval = rt2800pci_enable_radio(rt2x00dev); break; case STATE_RADIO_OFF: @@ -797,7 +809,33 @@ static void rt2800pci_pretbtt_tasklet(unsigned long data) static void rt2800pci_tbtt_tasklet(unsigned long data) { struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u32 reg; + rt2x00lib_beacondone(rt2x00dev); + + if (rt2x00dev->intf_ap_count) { + /* + * The rt2800pci hardware tbtt timer is off by 1us per tbtt + * causing beacon skew and as a result causing problems with + * some powersaving clients over time. Shorten the beacon + * interval every 64 beacons by 64us to mitigate this effect. + */ + if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16) - 1); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { + rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16)); + rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } + drv_data->tbtt_tick++; + drv_data->tbtt_tick %= BCN_TBTT_OFFSET; + } + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); } @@ -1050,6 +1088,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, .gain_calibration = rt2800_gain_calibration, + .vco_calibration = rt2800_vco_calibration, .start_queue = rt2800pci_start_queue, .kick_queue = rt2800pci_kick_queue, .stop_queue = rt2800pci_stop_queue, @@ -1093,6 +1132,7 @@ static const struct data_queue_desc rt2800pci_queue_bcn = { static const struct rt2x00_ops rt2800pci_ops = { .name = KBUILD_MODNAME, + .drv_data_size = sizeof(struct rt2800_drv_data), .max_sta_intf = 1, .max_ap_intf = 8, .eeprom_size = EEPROM_SIZE, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 262ee9eefb6..cd490abced9 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -114,45 +114,103 @@ static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) return false; } +static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) +{ + bool tout; + + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + return false; + + tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); + if (unlikely(tout)) + WARNING(entry->queue->rt2x00dev, + "TX status timeout for entry %d in queue %d\n", + entry->entry_idx, entry->queue->qid); + return tout; + +} + +static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800usb_entry_txstatus_timeout(entry)) + return true; + } + return false; +} + static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, int urb_status, u32 tx_status) { + bool valid; + if (urb_status) { - WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status); - return false; + WARNING(rt2x00dev, "TX status read failed %d\n", urb_status); + + goto stop_reading; } - /* try to read all TX_STA_FIFO entries before scheduling txdone_work */ - if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) { - if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) { - WARNING(rt2x00dev, "TX status FIFO overrun, " - "drop tx status report.\n"); - queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); - } else - return true; - } else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { + valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); + if (valid) { + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) + WARNING(rt2x00dev, "TX status FIFO overrun\n"); + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + + /* Reschedule urb to read TX status again instantly */ + return true; } else if (rt2800usb_txstatus_pending(rt2x00dev)) { - mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); + /* Read register after 250 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), + HRTIMER_MODE_REL); + return false; } - return false; +stop_reading: + clear_bit(TX_STATUS_READING, &rt2x00dev->flags); + /* + * There is small race window above, between txstatus pending check and + * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck + * here again if status reading is needed. + */ + if (rt2800usb_txstatus_pending(rt2x00dev) && + test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return true; + else + return false; +} + +static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) +{ + + if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return; + + /* Read TX_STA_FIFO register after 500 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), + HRTIMER_MODE_REL); } static void rt2800usb_tx_dma_done(struct queue_entry *entry) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, - rt2800usb_tx_sta_fifo_read_completed); + rt2800usb_async_read_tx_status(rt2x00dev); } -static void rt2800usb_tx_sta_fifo_timeout(unsigned long data) +static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer) { - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2x00_dev *rt2x00dev = + container_of(timer, struct rt2x00_dev, txstatus_timer); rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO, rt2800usb_tx_sta_fifo_read_completed); + + return HRTIMER_NORESTART; } /* @@ -226,9 +284,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); - rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - - rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); @@ -440,35 +496,26 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) /* * TX control handlers */ -static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) +static enum txdone_entry_desc_flags +rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) { __le32 *txwi; u32 word; int wcid, ack, pid; - int tx_wcid, tx_ack, tx_pid; - - if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || - !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) { - WARNING(entry->queue->rt2x00dev, - "Data pending for entry %u in queue %u\n", - entry->entry_idx, entry->queue->qid); - cond_resched(); - return false; - } - - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + int tx_wcid, tx_ack, tx_pid, is_agg; /* * This frames has returned with an IO error, * so the status report is not intended for this * frame. */ - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { - rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - return false; - } + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + return TXDONE_FAILURE; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); /* * Validate if this TX status report is intended for @@ -481,15 +528,14 @@ static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { + if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { WARNING(entry->queue->rt2x00dev, "TX status report missed for queue %d entry %d\n", - entry->queue->qid, entry->entry_idx); - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); - return false; + entry->queue->qid, entry->entry_idx); + return TXDONE_UNKNOWN; } - return true; + return TXDONE_SUCCESS; } static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) @@ -498,47 +544,44 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) struct queue_entry *entry; u32 reg; u8 qid; + enum txdone_entry_desc_flags done_status; while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { - - /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus - * qid is guaranteed to be one of the TX QIDs + /* + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is + * guaranteed to be one of the TX QIDs . */ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - if (unlikely(!queue)) { - WARNING(rt2x00dev, "Got TX status for an unavailable " + + if (unlikely(rt2x00queue_empty(queue))) { + WARNING(rt2x00dev, "Got TX status for an empty " "queue %u, dropping\n", qid); - continue; + break; } - /* - * Inside each queue, we process each entry in a chronological - * order. We first check that the queue is not empty. - */ - entry = NULL; - while (!rt2x00queue_empty(queue)) { - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - if (rt2800usb_txdone_entry_check(entry, reg)) - break; - entry = NULL; + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { + WARNING(rt2x00dev, "Data pending for entry %u " + "in queue %u\n", entry->entry_idx, qid); + break; } - if (entry) - rt2800_txdone_entry(entry, reg, - rt2800usb_get_txwi(entry)); + done_status = rt2800usb_txdone_entry_check(entry, reg); + if (likely(done_status == TXDONE_SUCCESS)) + rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry)); + else + rt2x00lib_txdone_noinfo(entry, done_status); } } -static void rt2800usb_work_txdone(struct work_struct *work) +static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) { - struct rt2x00_dev *rt2x00dev = - container_of(work, struct rt2x00_dev, txdone_work); struct data_queue *queue; struct queue_entry *entry; - rt2800usb_txdone(rt2x00dev); - /* * Process any trailing TX status reports for IO failures, * we loop until we find the first non-IO error entry. This @@ -556,20 +599,34 @@ static void rt2800usb_work_txdone(struct work_struct *work) if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - else if (rt2x00queue_status_timeout(entry)) + else if (rt2800usb_entry_txstatus_timeout(entry)) rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); else break; } } +} - /* - * The hw may delay sending the packet after DMA complete - * if the medium is busy, thus the TX_STA_FIFO entry is - * also delayed -> use a timer to retrieve it. - */ - if (rt2800usb_txstatus_pending(rt2x00dev)) - mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2)); +static void rt2800usb_work_txdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || + rt2800usb_txstatus_timeout(rt2x00dev)) { + + rt2800usb_txdone(rt2x00dev); + + rt2800usb_txdone_nostatus(rt2x00dev); + + /* + * The hw may delay sending the packet after DMA complete + * if the medium is busy, thus the TX_STA_FIFO entry is + * also delayed -> use a timer to retrieve it. + */ + if (rt2800usb_txstatus_pending(rt2x00dev)) + rt2800usb_async_read_tx_status(rt2x00dev); + } } /* @@ -711,9 +768,7 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags); __set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags); - setup_timer(&rt2x00dev->txstatus_timer, - rt2800usb_tx_sta_fifo_timeout, - (unsigned long) rt2x00dev); + rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout, /* * Set the rssi offset. @@ -783,6 +838,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, .gain_calibration = rt2800_gain_calibration, + .vco_calibration = rt2800_vco_calibration, .watchdog = rt2800usb_watchdog, .start_queue = rt2800usb_start_queue, .kick_queue = rt2x00usb_kick_queue, @@ -814,7 +870,7 @@ static const struct data_queue_desc rt2800usb_queue_rx = { }; static const struct data_queue_desc rt2800usb_queue_tx = { - .entry_num = 64, + .entry_num = 16, .data_size = AGGREGATION_SIZE, .desc_size = TXINFO_DESC_SIZE + TXWI_DESC_SIZE, .priv_size = sizeof(struct queue_entry_priv_usb), @@ -829,6 +885,7 @@ static const struct data_queue_desc rt2800usb_queue_bcn = { static const struct rt2x00_ops rt2800usb_ops = { .name = KBUILD_MODNAME, + .drv_data_size = sizeof(struct rt2800_drv_data), .max_sta_intf = 1, .max_ap_intf = 8, .eeprom_size = EEPROM_SIZE, @@ -922,6 +979,7 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c13) }, { USB_DEVICE(0x07d1, 0x3c15) }, { USB_DEVICE(0x07d1, 0x3c16) }, + { USB_DEVICE(0x2001, 0x3c1b) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712) }, /* DVICO */ @@ -1101,12 +1159,26 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x5a57, 0x0284) }, #endif #ifdef CONFIG_RT2800USB_RT53XX + /* Alpha */ + { USB_DEVICE(0x2001, 0x3c15) }, + { USB_DEVICE(0x2001, 0x3c19) }, + /* Arcadyan */ + { USB_DEVICE(0x043e, 0x7a12) }, /* Azurewave */ { USB_DEVICE(0x13d3, 0x3329) }, { USB_DEVICE(0x13d3, 0x3365) }, + /* LG innotek */ + { USB_DEVICE(0x043e, 0x7a22) }, + /* Panasonic */ + { USB_DEVICE(0x04da, 0x1801) }, + { USB_DEVICE(0x04da, 0x1800) }, + /* Philips */ + { USB_DEVICE(0x0471, 0x2104) }, /* Ralink */ { USB_DEVICE(0x148f, 0x5370) }, { USB_DEVICE(0x148f, 0x5372) }, + /* Unknown */ + { USB_DEVICE(0x04da, 0x23f6) }, #endif #ifdef CONFIG_RT2800USB_UNKNOWN /* diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index b03b22c47b1..471f87cab4a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -38,7 +38,7 @@ #include <linux/etherdevice.h> #include <linux/input-polldev.h> #include <linux/kfifo.h> -#include <linux/timer.h> +#include <linux/hrtimer.h> #include <net/mac80211.h> @@ -192,6 +192,7 @@ struct rt2x00_chip { #define RT3593 0x3593 #define RT3883 0x3883 /* WSOC */ #define RT5390 0x5390 /* 2.4GHz */ +#define RT5392 0x5392 /* 2.4GHz */ u16 rf; u16 rev; @@ -355,6 +356,11 @@ struct link { * Work structure for scheduling periodic AGC adjustments. */ struct delayed_work agc_work; + + /* + * Work structure for scheduling periodic VCO calibration. + */ + struct delayed_work vco_work; }; enum rt2x00_delayed_flags { @@ -579,6 +585,7 @@ struct rt2x00lib_ops { void (*link_tuner) (struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); + void (*vco_calibration) (struct rt2x00_dev *rt2x00dev); /* * Data queue handlers. @@ -647,6 +654,7 @@ struct rt2x00lib_ops { */ struct rt2x00_ops { const char *name; + const unsigned int drv_data_size; const unsigned int max_sta_intf; const unsigned int max_ap_intf; const unsigned int eeprom_size; @@ -684,6 +692,12 @@ enum rt2x00_state_flags { */ CONFIG_CHANNEL_HT40, CONFIG_POWERSAVING, + + /* + * Mark we currently are sequentially reading TX_STA_FIFO register + * FIXME: this is for only rt2800usb, should go to private data + */ + TX_STATUS_READING, }; /* @@ -721,6 +735,7 @@ enum rt2x00_capability_flags { CAPABILITY_EXTERNAL_LNA_BG, CAPABILITY_DOUBLE_ANTENNA, CAPABILITY_BT_COEXIST, + CAPABILITY_VCO_RECALIBRATION, }; /* @@ -742,6 +757,11 @@ struct rt2x00_dev { const struct rt2x00_ops *ops; /* + * Driver data. + */ + void *drv_data; + + /* * IEEE80211 control structure. */ struct ieee80211_hw *hw; @@ -886,18 +906,11 @@ struct rt2x00_dev { u8 rssi_offset; /* - * Frequency offset (for rt61pci & rt73usb). + * Frequency offset. */ u8 freq_offset; /* - * Calibration information (for rt2800usb & rt2800pci). - * [0] -> BW20 - * [1] -> BW40 - */ - u8 calibration[2]; - - /* * Association id. */ u16 aid; @@ -967,7 +980,7 @@ struct rt2x00_dev { /* * Timer to ensure tx status reports are read (rt2800usb). */ - struct timer_list txstatus_timer; + struct hrtimer txstatus_timer; /* * Tasklet for processing tx status reports (rt2800pci). @@ -979,6 +992,11 @@ struct rt2x00_dev { struct tasklet_struct autowake_tasklet; /* + * Used for VCO periodic calibration. + */ + int rf_channel; + + /* * Protect the interrupt mask register. */ spinlock_t irqmask_lock; diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index b704e5b183d..293676bfa57 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update the AID, this is needed for dynamic PS support */ rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; - rt2x00dev->last_beacon = bss_conf->timestamp; + rt2x00dev->last_beacon = bss_conf->last_tsf; /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; @@ -232,6 +232,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, memcpy(&libconf.channel, &rt2x00dev->spec.channels_info[hw_value], sizeof(libconf.channel)); + + /* Used for VCO periodic calibration */ + rt2x00dev->rf_channel = libconf.rf.channel; } if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index fd356b7c047..fc9901e027c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -88,6 +88,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) rt2x00queue_start_queues(rt2x00dev); rt2x00link_start_tuner(rt2x00dev); rt2x00link_start_agc(rt2x00dev); + if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags)) + rt2x00link_start_vcocal(rt2x00dev); /* * Start watchdog monitoring. @@ -111,6 +113,8 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) * Stop all queues */ rt2x00link_stop_agc(rt2x00dev); + if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags)) + rt2x00link_stop_vcocal(rt2x00dev); rt2x00link_stop_tuner(rt2x00dev); rt2x00queue_stop_queues(rt2x00dev); rt2x00queue_flush_queues(rt2x00dev, true); @@ -1125,6 +1129,18 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) { int retval = -ENOMEM; + /* + * Allocate the driver data memory, if necessary. + */ + if (rt2x00dev->ops->drv_data_size > 0) { + rt2x00dev->drv_data = kzalloc(rt2x00dev->ops->drv_data_size, + GFP_KERNEL); + if (!rt2x00dev->drv_data) { + retval = -ENOMEM; + goto exit; + } + } + spin_lock_init(&rt2x00dev->irqmask_lock); mutex_init(&rt2x00dev->csr_mutex); @@ -1220,7 +1236,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); cancel_work_sync(&rt2x00dev->sleep_work); if (rt2x00_is_usb(rt2x00dev)) { - del_timer_sync(&rt2x00dev->txstatus_timer); + hrtimer_cancel(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); } @@ -1266,6 +1282,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Free queue structures. */ rt2x00queue_free(rt2x00dev); + + /* + * Free the driver data. + */ + if (rt2x00dev->drv_data) + kfree(rt2x00dev->drv_data); } EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 4cdf247a870..78bd43b8961 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -33,6 +33,7 @@ #define WATCHDOG_INTERVAL round_jiffies_relative(HZ) #define LINK_TUNE_INTERVAL round_jiffies_relative(HZ) #define AGC_INTERVAL round_jiffies_relative(4 * HZ) +#define VCO_INTERVAL round_jiffies_relative(10 * HZ) /* 10 sec */ /* * rt2x00_rate: Per rate device information @@ -278,12 +279,24 @@ void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev); void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev); /** + * rt2x00link_start_vcocal - Start periodic VCO calibration + * @rt2x00dev: Pointer to &struct rt2x00_dev. + */ +void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev); + +/** * rt2x00link_stop_agc - Stop periodic gain calibration * @rt2x00dev: Pointer to &struct rt2x00_dev. */ void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev); /** + * rt2x00link_stop_vcocal - Stop periodic VCO calibration + * @rt2x00dev: Pointer to &struct rt2x00_dev. + */ +void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev); + +/** * rt2x00link_register - Initialize link tuning & watchdog functionality * @rt2x00dev: Pointer to &struct rt2x00_dev. * diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index ea10b0068f8..8368aab86f2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -447,11 +447,27 @@ void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev) AGC_INTERVAL); } +void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev) +{ + struct link *link = &rt2x00dev->link; + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + rt2x00dev->ops->lib->vco_calibration) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->vco_work, + VCO_INTERVAL); +} + void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev) { cancel_delayed_work_sync(&rt2x00dev->link.agc_work); } +void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev) +{ + cancel_delayed_work_sync(&rt2x00dev->link.vco_work); +} + static void rt2x00link_agc(struct work_struct *work) { struct rt2x00_dev *rt2x00dev = @@ -473,9 +489,32 @@ static void rt2x00link_agc(struct work_struct *work) AGC_INTERVAL); } +static void rt2x00link_vcocal(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, link.vco_work.work); + struct link *link = &rt2x00dev->link; + + /* + * When the radio is shutting down we should + * immediately cease the VCO calibration. + */ + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return; + + rt2x00dev->ops->lib->vco_calibration(rt2x00dev); + + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + ieee80211_queue_delayed_work(rt2x00dev->hw, + &link->vco_work, + VCO_INTERVAL); +} + void rt2x00link_register(struct rt2x00_dev *rt2x00dev) { INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc); + if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags)) + INIT_DELAYED_WORK(&rt2x00dev->link.vco_work, rt2x00link_vcocal); INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); } diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 349008d1fb2..5f1392c7267 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -636,18 +636,6 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) { return rt2x00queue_available(queue) < queue->threshold; } - -/** - * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports - * @entry: Queue entry to check. - */ -static inline int rt2x00queue_status_timeout(struct queue_entry *entry) -{ - if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) - return false; - return time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); -} - /** * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers * @entry: Queue entry to check. diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 2eea3866504..66094eb21b6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -526,22 +526,6 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) rt2x00queue_flush_queue(queue, true); } -static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) -{ - WARNING(queue->rt2x00dev, "TX queue %d status timed out," - " invoke forced tx handler\n", queue->qid); - - queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work); -} - -static int rt2x00usb_status_timeout(struct data_queue *queue) -{ - struct queue_entry *entry; - - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - return rt2x00queue_status_timeout(entry); -} - static int rt2x00usb_dma_timeout(struct data_queue *queue) { struct queue_entry *entry; @@ -558,8 +542,6 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) if (!rt2x00queue_empty(queue)) { if (rt2x00usb_dma_timeout(queue)) rt2x00usb_watchdog_tx_dma(queue); - if (rt2x00usb_status_timeout(queue)) - rt2x00usb_watchdog_tx_status(queue); } } } @@ -829,7 +811,8 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); - init_timer(&rt2x00dev->txstatus_timer); + hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); retval = rt2x00usb_alloc_reg(rt2x00dev); if (retval) diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 638fbef693e..cf53ac9d6f2 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -8,7 +8,7 @@ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. * * The driver was extended to the RTL8187B in 2008 by: - * Herton Ronaldo Krzesinski <herton@mandriva.com.br> + * Herton Ronaldo Krzesinski <herton@mandriva.com.br> * Hin-Tak Leung <htl10@users.sourceforge.net> * Larry Finger <Larry.Finger@lwfinger.net> * @@ -232,6 +232,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct rtl8187_priv *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *tx_hdr = (struct ieee80211_hdr *)(skb->data); unsigned int ep; void *buf; struct urb *urb; @@ -249,7 +250,7 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) flags |= RTL818X_TX_DESC_FLAG_NO_ENC; flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; - if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) + if (ieee80211_has_morefrags(tx_hdr->frame_control)) flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { flags |= RTL818X_TX_DESC_FLAG_RTS; @@ -261,6 +262,13 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; } + if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { + if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) + priv->seqno += 0x10; + tx_hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); + tx_hdr->seq_ctrl |= cpu_to_le16(priv->seqno); + } + if (!priv->is_rtl8187b) { struct rtl8187_tx_hdr *hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); @@ -274,8 +282,6 @@ static void rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) } else { /* fc needs to be calculated before skb_push() */ unsigned int epmap[4] = { 6, 7, 5, 4 }; - struct ieee80211_hdr *tx_hdr = - (struct ieee80211_hdr *)(skb->data); u16 fc = le16_to_cpu(tx_hdr->frame_control); struct rtl8187b_tx_hdr *hdr = @@ -1031,10 +1037,61 @@ static void rtl8187_stop(struct ieee80211_hw *dev) cancel_delayed_work_sync(&priv->work); } +static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) +{ + struct rtl8187_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + + +static void rtl8187_beacon_work(struct work_struct *work) +{ + struct rtl8187_vif *vif_priv = + container_of(work, struct rtl8187_vif, beacon_work.work); + struct ieee80211_vif *vif = + container_of((void *)vif_priv, struct ieee80211_vif, drv_priv); + struct ieee80211_hw *dev = vif_priv->dev; + struct ieee80211_mgmt *mgmt; + struct sk_buff *skb; + + /* don't overflow the tx ring */ + if (ieee80211_queue_stopped(dev, 0)) + goto resched; + + /* grab a fresh beacon */ + skb = ieee80211_beacon_get(dev, vif); + if (!skb) + goto resched; + + /* + * update beacon timestamp w/ TSF value + * TODO: make hardware update beacon timestamp + */ + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->u.beacon.timestamp = cpu_to_le64(rtl8187_get_tsf(dev, vif)); + + /* TODO: use actual beacon queue */ + skb_set_queue_mapping(skb, 0); + + rtl8187_tx(dev, skb); + +resched: + /* + * schedule next beacon + * TODO: use hardware support for beacon timing + */ + schedule_delayed_work(&vif_priv->beacon_work, + usecs_to_jiffies(1024 * vif->bss_conf.beacon_int)); +} + + static int rtl8187_add_interface(struct ieee80211_hw *dev, struct ieee80211_vif *vif) { struct rtl8187_priv *priv = dev->priv; + struct rtl8187_vif *vif_priv; int i; int ret = -EOPNOTSUPP; @@ -1044,6 +1101,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, switch (vif->type) { case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: break; default: goto exit; @@ -1052,6 +1110,13 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev, ret = 0; priv->vif = vif; + /* Initialize driver private area */ + vif_priv = (struct rtl8187_vif *)&vif->drv_priv; + vif_priv->dev = dev; + INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8187_beacon_work); + vif_priv->enable_beacon = false; + + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); for (i = 0; i < ETH_ALEN; i++) rtl818x_iowrite8(priv, &priv->map->MAC[i], @@ -1175,9 +1240,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, u32 changed) { struct rtl8187_priv *priv = dev->priv; + struct rtl8187_vif *vif_priv; int i; u8 reg; + vif_priv = (struct rtl8187_vif *)&vif->drv_priv; + if (changed & BSS_CHANGED_BSSID) { mutex_lock(&priv->conf_mutex); for (i = 0; i < ETH_ALEN; i++) @@ -1189,8 +1257,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, else reg = 0; - if (is_valid_ether_addr(info->bssid)) - reg |= RTL818X_MSR_INFRA; + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg |= RTL818X_MSR_ADHOC; + else + reg |= RTL818X_MSR_INFRA; + } else reg |= RTL818X_MSR_NO_LINK; @@ -1202,6 +1274,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) rtl8187_conf_erp(priv, info->use_short_slot, info->use_short_preamble); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + vif_priv->enable_beacon = info->enable_beacon; + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) { + cancel_delayed_work_sync(&vif_priv->beacon_work); + if (vif_priv->enable_beacon) + schedule_work(&vif_priv->beacon_work.work); + } + } static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev, @@ -1279,13 +1361,6 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, return 0; } -static u64 rtl8187_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) -{ - struct rtl8187_priv *priv = dev->priv; - - return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | - (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; -} static const struct ieee80211_ops rtl8187_ops = { .tx = rtl8187_tx, @@ -1514,12 +1589,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, if (reg & 0xFF00) priv->rfkill_mask = RFKILL_MASK_8198; } - - /* - * XXX: Once this driver supports anything that requires - * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ. - */ - dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + dev->vif_data_size = sizeof(struct rtl8187_vif); + dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) ; if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b) printk(KERN_INFO "rtl8187: inconsistency between id with OEM" diff --git a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h index f1cc90751db..e19a20a8e95 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h +++ b/drivers/net/wireless/rtl818x/rtl8187/rtl8187.h @@ -89,6 +89,14 @@ enum { DEVICE_RTL8187B }; +struct rtl8187_vif { + struct ieee80211_hw *dev; + + /* beaconing */ + struct delayed_work beacon_work; + bool enable_beacon; +}; + struct rtl8187_priv { /* common between rtl818x drivers */ struct rtl818x_csr *map; @@ -141,6 +149,7 @@ struct rtl8187_priv { __le32 bits32; } *io_dmabuf; bool rfkill_off; + u16 seqno; }; void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index d6c42e69bdb..cefac6a4360 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -49,6 +49,11 @@ config RTLWIFI depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE default m +config RTLWIFI_DEBUG + bool "Additional debugging output" + depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE + default y + config RTL8192C_COMMON tristate depends on RTL8192CE || RTL8192CU diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 8d6eb0f56c0..510023554e5 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,10 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/ip.h> -#include <linux/module.h> #include "wifi.h" #include "rc.h" #include "base.h" @@ -39,11 +35,14 @@ #include "ps.h" #include "regd.h" +#include <linux/ip.h> +#include <linux/module.h> + /* - *NOTICE!!!: This file will be very big, we hsould - *keep it clear under follwing roles: + *NOTICE!!!: This file will be very big, we should + *keep it clear under following roles: * - *This file include follwing part, so, if you add new + *This file include following parts, so, if you add new *functions into this file, please check which part it *should includes. or check if you should add new part *for this file: @@ -211,7 +210,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, */ if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; @@ -220,7 +219,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; @@ -302,15 +301,13 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Err BAND %d\n", - rtlhal->current_bandtype)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n", + rtlhal->current_bandtype); } } /* <5> set hw caps */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_CONNECTION_MONITOR | /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */ @@ -413,6 +410,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) wiphy_rfkill_start_polling(hw->wiphy); } +EXPORT_SYMBOL(rtl_init_rfkill); void rtl_deinit_rfkill(struct ieee80211_hw *hw) { @@ -436,13 +434,13 @@ int rtl_init_core(struct ieee80211_hw *hw) * mac80211 hw in _rtl_init_mac80211. */ if (rtl_regd_init(hw, rtl_reg_notifier)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n"); return 1; } else { /* CRDA regd hint must after init CRDA */ if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("regulatory_hint fail\n")); + "regulatory_hint fail\n"); } } @@ -922,17 +920,17 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return false; RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBAREQ From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBAREQ From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_ADDBARSP: RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBARSP From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_DELBA: RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("ACT_ADDBADEL From :%pM\n", hdr->addr2)); + "ACT_ADDBADEL From :%pM\n", hdr->addr2); break; } break; @@ -975,8 +973,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) * 67 : UDP BOOTP server */ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), - DBG_DMESG, ("dhcp %s !!\n", - (is_tx) ? "Tx" : "Rx")); + DBG_DMESG, "dhcp %s !!\n", + is_tx ? "Tx" : "Rx"); if (is_tx) { rtl_lps_leave(hw); @@ -996,7 +994,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return true; } else if (ETH_P_PAE == ether_type) { RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx")); + "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { rtl_lps_leave(hw); @@ -1036,9 +1034,8 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n", + sta->addr, tid, tid_data->seq_number); *ssn = tid_data->seq_number; tid_data->agg.agg_state = RTL_AGG_START; @@ -1059,12 +1056,12 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, return -EINVAL; if (!sta->addr) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; } - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1087,12 +1084,12 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, return -EINVAL; if (!sta->addr) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; } - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1474,29 +1471,29 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) (memcmp(mac->bssid, ap5_6, 3) == 0) || vendor == PEER_ATH) { vendor = PEER_ATH; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || (memcmp(mac->bssid, ap4_5, 3) == 0) || (memcmp(mac->bssid, ap4_1, 3) == 0) || (memcmp(mac->bssid, ap4_2, 3) == 0) || (memcmp(mac->bssid, ap4_3, 3) == 0) || vendor == PEER_RAL) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); vendor = PEER_RAL; } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || vendor == PEER_CISCO) { vendor = PEER_CISCO; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || (memcmp(mac->bssid, ap3_2, 3) == 0) || (memcmp(mac->bssid, ap3_3, 3) == 0) || vendor == PEER_BROAD) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); vendor = PEER_BROAD; } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || vendor == PEER_MARV) { vendor = PEER_MARV; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); } mac->vendor = vendor; diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index f66b5757f6b..5a23a6d0f49 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index dc36d7461ca..5c7d57947d2 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include <linux/export.h> #include "wifi.h" #include "cam.h" @@ -55,10 +53,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, u8 entry_i; RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", - key_cont_128[0], key_cont_128[1], - key_cont_128[2], key_cont_128[3], - key_cont_128[4], key_cont_128[5])); + "key_cont_128:\n %x:%x:%x:%x:%x:%x\n", + key_cont_128[0], key_cont_128[1], + key_cont_128[2], key_cont_128[3], + key_cont_128[4], key_cont_128[5]); for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { target_command = entry_i + CAM_CONTENT_COUNT * entry_no; @@ -73,14 +71,12 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[WCAMI], target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The Key ID is %d\n", entry_no)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[RWCAM], target_command)); + "The Key ID is %d\n", entry_no); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); } else if (entry_i == 1) { @@ -94,10 +90,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } else { @@ -114,15 +110,15 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, target_command); udelay(100); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("after set key, usconfig:%x\n", us_config)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "after set key, usconfig:%x\n", + us_config); } u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, @@ -133,14 +129,13 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, " - "ulUseDK=%x MacAddr %pM\n", - ul_entry_idx, ul_key_id, ul_enc_alg, - ul_default_key, mac_addr)); + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, mac_addr); if (ul_key_id == TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("<=== ulKeyId exceed!\n")); + "<=== ulKeyId exceed!\n"); return 0; } @@ -153,7 +148,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, (u8 *) key_content, us_config); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n"); return 1; @@ -166,7 +161,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u32 ul_command; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); ul_command = ul_key_id * CAM_CONTENT_COUNT; ul_command = ul_command | BIT(31) | BIT(16); @@ -175,9 +170,9 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0)); + "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command)); + "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command); return 0; @@ -229,9 +224,9 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content)); + "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command)); + "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command); } EXPORT_SYMBOL(rtl_cam_mark_invalid); @@ -279,11 +274,11 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("rtl_cam_empty_entry(): WRITE A4: %x\n", - ul_content)); + "rtl_cam_empty_entry(): WRITE A4: %x\n", + ul_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("rtl_cam_empty_entry(): WRITE A0: %x\n", - ul_command)); + "rtl_cam_empty_entry(): WRITE A0: %x\n", + ul_command); } } @@ -297,8 +292,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); return TOTAL_CAM_ENTRY; } /* Does STA already exist? */ @@ -311,8 +305,8 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { if ((bitmap & BIT(0)) == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", - rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); + "-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", + rtlpriv->sec.hwsec_cam_bitmap, entry_idx); rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], sta_addr, ETH_ALEN); @@ -331,14 +325,13 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); } if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\ sta_addr[4]|sta_addr[5]) == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is 00:00:00:00:00:00.\n")); + "sta_addr is 00:00:00:00:00:00\n"); return; } /* Does STA already exist? */ diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index c62da4eefc7..35e00086a52 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 3f0f056fae9..278e9f957e0 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -31,8 +31,50 @@ #include "core.h" #include "cam.h" #include "base.h" +#include "pci.h" #include "ps.h" +#include <linux/export.h> + +void rtl_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } + if (firmware->size > rtlpriv->max_fw_size) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Firmware is too big!\n"); + release_firmware(firmware); + return; + } + memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); + rtlpriv->rtlhal.fwsize = firmware->size; + release_firmware(firmware); + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw\n"); + return; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /*init rfkill */ + rtl_init_rfkill(hw); +} +EXPORT_SYMBOL(rtl_fw_cb); + /*mutex for start & stop is must here. */ static int rtl_op_start(struct ieee80211_hw *hw) { @@ -112,9 +154,11 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); int err = 0; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + if (mac->vif) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("vif has been set!! mac->vif = 0x%p\n", mac->vif)); + "vif has been set!! mac->vif = 0x%p\n", mac->vif); return -EOPNOTSUPP; } @@ -125,7 +169,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_STATION\n")); + "NL80211_IFTYPE_STATION\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, rtlpriv->cfg->maps @@ -134,7 +178,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_ADHOC: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_ADHOC\n")); + "NL80211_IFTYPE_ADHOC\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -148,7 +192,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_AP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_AP\n")); + "NL80211_IFTYPE_AP\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -161,7 +205,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("operation mode %d is not support!\n", vif->type)); + "operation mode %d is not supported!\n", vif->type); err = -EOPNOTSUPP; goto out; } @@ -221,7 +265,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); } /*For IPS */ @@ -264,8 +308,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", - hw->conf.long_frame_max_tx_count)); + "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count); mac->retry_long = hw->conf.long_frame_max_tx_count; mac->retry_short = hw->conf.long_frame_max_tx_count; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, @@ -320,7 +364,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) default: mac->bw_40 = false; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not processed\n")); + "switch case not processed\n"); break; } @@ -369,12 +413,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive multicast frame.\n")); + "Enable receive multicast frame\n"); } else { mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]); RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive multicast frame.\n")); + "Disable receive multicast frame\n"); } } @@ -382,11 +426,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_FCSFAIL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive FCS error frame.\n")); + "Enable receive FCS error frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive FCS error frame.\n")); + "Disable receive FCS error frame\n"); } } @@ -409,11 +453,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive control frame.\n")); + "Enable receive control frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive control frame.\n")); + "Disable receive control frame\n"); } } @@ -421,11 +465,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_OTHER_BSS) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive other BSS's frame.\n")); + "Enable receive other BSS's frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive other BSS's frame.\n")); + "Disable receive other BSS's frame\n"); } } } @@ -456,7 +500,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta_entry->wireless_mode = WIRELESS_MODE_G; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("Add sta addr is %pM\n", sta->addr)); + "Add sta addr is %pM\n", sta->addr); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); } return 0; @@ -469,7 +513,7 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry; if (sta) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("Remove sta addr is %pM\n", sta->addr)); + "Remove sta addr is %pM\n", sta->addr); sta_entry = (struct rtl_sta_info *) sta->drv_priv; sta_entry->wireless_mode = 0; sta_entry->ratr_index = 0; @@ -514,7 +558,7 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, if (queue >= AC_MAX) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("queue number %d is incorrect!\n", queue)); + "queue number %d is incorrect!\n", queue); return -EINVAL; } @@ -547,7 +591,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, bss_conf->enable_beacon)) { if (mac->beacon_enabled == 0) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_BEACON_ENABLED\n")); + "BSS_CHANGED_BEACON_ENABLED\n"); /*start hw beacon interrupt. */ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ @@ -565,7 +609,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, !bss_conf->enable_beacon)) { if (mac->beacon_enabled == 1) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("ADHOC DISABLE BEACON\n")); + "ADHOC DISABLE BEACON\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, @@ -575,7 +619,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, - ("BSS_CHANGED_BEACON_INT\n")); + "BSS_CHANGED_BEACON_INT\n"); mac->beacon_interval = bss_conf->beacon_int; rtlpriv->cfg->ops->set_bcn_intv(hw); } @@ -604,7 +648,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (mac->opmode == NL80211_IFTYPE_STATION && sta) rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_ASSOC\n")); + "BSS_CHANGED_ASSOC\n"); } else { if (mac->link_state == MAC80211_LINKED) rtl_lps_leave(hw); @@ -619,20 +663,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->vendor = PEER_UNKNOWN; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_UN_ASSOC\n")); + "BSS_CHANGED_UN_ASSOC\n"); } } if (changed & BSS_CHANGED_ERP_CTS_PROT) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_CTS_PROT\n")); + "BSS_CHANGED_ERP_CTS_PROT\n"); mac->use_cts_protect = bss_conf->use_cts_prot; } if (changed & BSS_CHANGED_ERP_PREAMBLE) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", - bss_conf->use_short_preamble)); + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + bss_conf->use_short_preamble); mac->short_preamble = bss_conf->use_short_preamble; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, @@ -641,7 +685,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ERP_SLOT) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_SLOT\n")); + "BSS_CHANGED_ERP_SLOT\n"); if (bss_conf->use_short_slot) mac->slot_time = RTL_SLOT_TIME_9; @@ -653,8 +697,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_HT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_HT\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n"); rcu_read_lock(); sta = get_sta(hw, vif, bss_conf->bssid); if (sta) { @@ -683,8 +726,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, (u8 *) bss_conf->bssid); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("%pM\n", bss_conf->bssid)); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, "%pM\n", + bss_conf->bssid); mac->vendor = PEER_UNKNOWN; memcpy(mac->bssid, bss_conf->bssid, 6); @@ -831,30 +874,30 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_TX_START: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); return rtl_tx_agg_start(hw, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); return rtl_tx_agg_stop(hw, sta, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); rtl_tx_agg_oper(hw, sta, tid); break; case IEEE80211_AMPDU_RX_START: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); break; case IEEE80211_AMPDU_RX_STOP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("IEEE80211_AMPDU_ERR!!!!:\n")); + "IEEE80211_AMPDU_ERR!!!!:\n"); return -EOPNOTSUPP; } return 0; @@ -867,7 +910,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) mac->act_scanning = true; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); if (mac->link_state == MAC80211_LINKED) { rtl_lps_leave(hw); @@ -888,7 +931,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = false; /* Dual mac */ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; @@ -921,13 +964,13 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("not open hw encryption\n")); + "not open hw encryption\n"); return -ENOSPC; /*User disabled HW-crypto */ } RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("%s hardware based encryption for keyidx: %d, mac: %pM\n", - cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - sta ? sta->addr : bcast_addr)); + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); rtlpriv->sec.being_setkey = true; rtl_ips_nic_on(hw); mutex_lock(&rtlpriv->locks.conf_mutex); @@ -936,24 +979,23 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: key_type = WEP40_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("alg:WEP104\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); key_type = WEP104_ENCRYPTION; break; case WLAN_CIPHER_SUITE_TKIP: key_type = TKIP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); break; case WLAN_CIPHER_SUITE_CCMP: key_type = AESCCMP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("alg_err:%x!!!!:\n", key->cipher)); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n", + key->cipher); goto out_unlock; } if (key_type == WEP40_ENCRYPTION || @@ -995,8 +1037,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wep_only = true; rtlpriv->sec.pairwise_enc_algorithm = key_type; RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" - " TKIP:2 AES:4 WEP104:5)\n", key_type)); + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); rtlpriv->cfg->ops->enable_hw_sec(hw); } } @@ -1005,7 +1047,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case SET_KEY: if (wep_only) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set WEP(group/pairwise) key\n")); + "set WEP(group/pairwise) key\n"); /* Pairwise key with an assigned MAC address. */ rtlpriv->sec.pairwise_enc_algorithm = key_type; rtlpriv->sec.group_enc_algorithm = key_type; @@ -1016,7 +1058,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(mac_addr, zero_addr, ETH_ALEN); } else if (group_key) { /* group key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); /* group key */ rtlpriv->sec.group_enc_algorithm = key_type; /*set local buf about group key. */ @@ -1026,10 +1068,10 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(mac_addr, bcast_addr, ETH_ALEN); } else { /* pairwise key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set pairwise key\n")); + "set pairwise key\n"); if (!sta) { - RT_ASSERT(false, ("pairwise key withnot" - "mac_addr\n")); + RT_ASSERT(false, + "pairwise key without mac_addr\n"); err = -EOPNOTSUPP; goto out_unlock; @@ -1056,7 +1098,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; case DISABLE_KEY: RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("disable key delete one entry\n")); + "disable key delete one entry\n"); /*set local buf about wep key. */ if (mac->opmode == NL80211_IFTYPE_AP) { if (sta) @@ -1077,7 +1119,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("cmd_err:%x!!!!:\n", cmd)); + "cmd_err:%x!!!!\n", cmd); } out_unlock: mutex_unlock(&rtlpriv->locks.conf_mutex); @@ -1106,8 +1148,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) rtlpriv->rfkill.rfkill_state = radio_state; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - (KERN_INFO "wireless radio switch turned %s\n", - radio_state ? "on" : "off")); + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; wiphy_rfkill_set_hw_state(hw->wiphy, blocked); diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index f02824a3b74..2fe46a1b4f1 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis 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 @@ -30,8 +30,6 @@ #ifndef __RTL_CORE_H__ #define __RTL_CORE_H__ -#include <net/mac80211.h> - #define RTL_SUPPORTED_FILTERS \ (FIF_PROMISC_IN_BSS | \ FIF_ALLMULTI | FIF_CONTROL | \ @@ -42,4 +40,6 @@ #define RTL_SUPPORTED_CTRL_FILTER 0xFF extern const struct ieee80211_ops rtl_ops; +void rtl_fw_cb(const struct firmware *firmware, void *context); + #endif diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c index 1b5cb7153a5..bdda9b2fffe 100644 --- a/drivers/net/wireless/rtlwifi/debug.c +++ b/drivers/net/wireless/rtlwifi/debug.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis 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 @@ -28,6 +28,8 @@ #include "wifi.h" +#include <linux/moduleparam.h> + void rtl_dbgp_flag_init(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 160dd068521..07493d2957f 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis 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 @@ -156,53 +156,78 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; -#define RT_ASSERT(_exp, fmt) \ - do { \ - if (!(_exp)) { \ - printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \ - __func__); \ - printk fmt; \ - } \ - } while (0); - -#define RT_TRACE(rtlpriv, comp, level, fmt)\ - do { \ - if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ - ((level) <= rtlpriv->dbg.global_debuglevel))) {\ - printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \ - __func__, in_interrupt(), in_atomic()); \ - printk fmt; \ - } \ - } while (0); - -#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ - do { \ - if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk printstr; \ - } \ - } while (0); - -#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ - _hexdatalen) \ - do {\ - if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\ - (_level <= rtlpriv->dbg.global_debuglevel))) { \ - int __i; \ - u8* ptr = (u8 *)_hexdata; \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk("In process \"%s\" (pid %i):", current->comm,\ - current->pid); \ - printk(_titlestring); \ - for (__i = 0; __i < (int)_hexdatalen; __i++) { \ - printk("%02X%s", ptr[__i], (((__i + 1) % 4)\ - == 0) ? " " : " ");\ - if (((__i + 1) % 16) == 0) \ - printk("\n"); \ - } \ - printk(KERN_DEBUG "\n"); \ - } \ - } while (0); +#ifdef CONFIG_RTLWIFI_DEBUG + +#define RT_ASSERT(_exp, fmt, ...) \ +do { \ + if (!(_exp)) { \ + printk(KERN_DEBUG KBUILD_MODNAME ":%s(): " fmt, \ + __func__, ##__VA_ARGS__); \ + } \ +} while (0) + +#define RT_TRACE(rtlpriv, comp, level, fmt, ...) \ +do { \ + if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ + ((level) <= rtlpriv->dbg.global_debuglevel))) { \ + printk(KERN_DEBUG KBUILD_MODNAME ":%s():<%lx-%x> " fmt, \ + __func__, in_interrupt(), in_atomic(), \ + ##__VA_ARGS__); \ + } \ +} while (0) + +#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \ +do { \ + if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ + printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ + ##__VA_ARGS__); \ + } \ +} while (0) + +#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ + _hexdatalen) \ +do { \ + if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \ + (_level <= rtlpriv->dbg.global_debuglevel))) { \ + printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \ + KBUILD_MODNAME, current->comm, current->pid, \ + _titlestring); \ + print_hex_dump_bytes("", DUMP_PREFIX_NONE, \ + _hexdata, _hexdatalen); \ + } \ +} while (0) + +#else + +struct rtl_priv; + +__printf(2, 3) +static inline void RT_ASSERT(int exp, const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RT_TRACE(struct rtl_priv *rtlpriv, + int comp, int level, + const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RTPRINT(struct rtl_priv *rtlpriv, + int dbgtype, int dbgflag, + const char *fmt, ...) +{ +} + +static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv, + int comp, int level, + const char *titlestring, + const void *hexdata, size_t hexdatalen) +{ +} + +#endif void rtl_dbgp_flag_init(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index ed1058b7158..1f143800a8d 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis 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 @@ -162,8 +162,8 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) const u32 efuse_len = rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("Addr=%x Data =%x\n", address, value)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", + address, value); if (address < efuse_len) { rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); @@ -252,8 +252,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("read_efuse(): Invalid offset(%#x) with read " - "bytes(%#x)!!\n", _offset, _size_byte)); + "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", + _offset, _size_byte); return; } @@ -280,7 +280,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if (*rtemp8 != 0xFF) { efuse_utilized++; RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("Addr=%d\n", efuse_addr)); + "Addr=%d\n", efuse_addr); efuse_addr++; } @@ -290,13 +290,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if (offset < efuse_max_section) { wren = (*rtemp8 & 0x0f); RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("offset-%d Worden=%x\n", offset, wren)); + "offset-%d Worden=%x\n", offset, wren); for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { if (!(wren & 0x01)) { RTPRINT(rtlpriv, FEEPROM, - EFUSE_READ_ALL, ("Addr=%d\n", - efuse_addr)); + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); efuse_addr++; @@ -308,8 +308,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) break; RTPRINT(rtlpriv, FEEPROM, - EFUSE_READ_ALL, ("Addr=%d\n", - efuse_addr)); + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); efuse_addr++; @@ -326,7 +326,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) } RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("Addr=%d\n", efuse_addr)); + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) { efuse_utilized++; @@ -395,9 +395,8 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) result = false; RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("efuse_shadow_update_chk(): totalbytes(%#x), " - "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", - totalbytes, hdr_num, words_need, efuse_used)); + "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + totalbytes, hdr_num, words_need, efuse_used); return result; } @@ -434,7 +433,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) u8 word_en = 0x0F; u8 first_pg = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n")); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "--->\n"); if (!efuse_shadow_update_chk(hw)) { efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); @@ -443,7 +442,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("<---efuse out of capacity!!\n")); + "<---efuse out of capacity!!\n"); return false; } efuse_power_switch(hw, true, true); @@ -478,12 +477,12 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base], 8); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, - ("U-efuse\n"), tmpdata, 8); + "U-efuse", tmpdata, 8); if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("PG section(%#x) fail!!\n", offset)); + "PG section(%#x) fail!!\n", offset); break; } } @@ -497,7 +496,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n")); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "<---\n"); return true; } @@ -634,8 +633,8 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmpidx = 0; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("Addr = %x Data=%x\n", addr, data)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n", + addr, data); rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -778,7 +777,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, dataempty = false; } - if (dataempty == false) { + if (!dataempty) { *efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1; *write_state = PG_STATE_HEADER; } else { @@ -851,7 +850,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } } } - RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n")); + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); } static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, @@ -916,7 +915,7 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER-2\n")); + "efuse PG_STATE_HEADER-2\n"); } } @@ -936,7 +935,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse_pg_packet_write error\n")); + "efuse_pg_packet_write error\n"); return false; } @@ -948,7 +947,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, efuse_word_enable_data_read(word_en, data, target_pkt.data); target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); - RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n")); + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); while (continual && (efuse_addr < (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { @@ -956,7 +955,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (write_state == PG_STATE_HEADER) { badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER\n")); + "efuse PG_STATE_HEADER\n"); if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) @@ -976,7 +975,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, } else if (write_state == PG_STATE_DATA) { RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_DATA\n")); + "efuse PG_STATE_DATA\n"); badworden = efuse_word_enable_data_write(hw, efuse_addr + 1, target_pkt.word_en, @@ -999,14 +998,14 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, result = false; } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER-3\n")); + "efuse PG_STATE_HEADER-3\n"); } } } if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("efuse_addr(%#x) Out of size!!\n", efuse_addr)); + "efuse_addr(%#x) Out of size!!\n", efuse_addr); } return true; @@ -1046,8 +1045,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, u8 tmpdata[8]; memset(tmpdata, 0xff, PGPKT_DATA_SIZE); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n", + word_en, efuse_addr); if (!(word_en & BIT(0))) { tmpaddr = start_addr; diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 164dabaa761..2bdea9a8699 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 9245d882c06..07dd38efe62 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,13 +27,13 @@ * *****************************************************************************/ -#include <linux/export.h> -#include "core.h" #include "wifi.h" +#include "core.h" #include "pci.h" #include "base.h" #include "ps.h" #include "efuse.h" +#include <linux/export.h> static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { PCI_VENDOR_ID_INTEL, @@ -170,7 +170,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -198,7 +198,7 @@ static bool _rtl_pci_platform_switch_device_pci_aspm( } /*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ -static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) +static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -207,8 +207,6 @@ static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) udelay(100); - - return true; } /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/ @@ -232,7 +230,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + "PCI(Bridge) UNKNOWN\n"); return; } @@ -286,7 +284,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + "PCI(Bridge) UNKNOWN\n"); return; } @@ -303,11 +301,10 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) u_pcibridge_aspmsetting); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PlatformEnableASPM():PciBridge busnumber[%x], " - "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", - pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting)); + "PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, + (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), + u_pcibridge_aspmsetting); udelay(50); @@ -382,9 +379,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Link Control Register =%x\n", - pcipriv->ndis_adapter.linkctrl_reg)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT(4); @@ -551,11 +547,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) skb_pull(skb, EM_HDR_LEN); RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, - ("new ring->idx:%d, " - "free: skb_queue_len:%d, free: seq:%x\n", - ring->idx, - skb_queue_len(&ring->queue), - *(u16 *) (skb->data + 22))); + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *) (skb->data + 22)); if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); @@ -593,11 +588,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) == 2) { RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - ("more desc left, wake" - "skb_queue@%d,ring->idx = %d," - "skb_queue_len = 0x%d\n", - prio, ring->idx, - skb_queue_len(&ring->queue))); + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); ieee80211_wake_queue(hw, skb_get_queue_mapping @@ -657,6 +650,8 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb, return; uskb = dev_alloc_skb(skb->len + 128); + if (!uskb) + return; /* exit if allocation failed */ memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status)); pdata = (u8 *)skb_put(uskb, skb->len); memcpy(pdata, skb->data, skb->len); @@ -709,9 +704,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) new_skb = dev_alloc_skb(rtlpci->rxbuffersize); if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), DBG_DMESG, + "can't alloc skb for rx\n"); goto done; } @@ -796,38 +790,37 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) /*<1> beacon related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon ok interrupt!\n")); + "beacon ok interrupt!\n"); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon err interrupt!\n")); + "beacon err interrupt!\n"); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon interrupt!\n")); + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("prepare beacon for interrupt!\n")); + "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<3> Tx related */ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("Manage ok interrupt!\n")); + "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("HIGH_QUEUE ok interrupt!\n")); + "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } @@ -835,7 +828,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("BK Tx OK interrupt!\n")); + "BK Tx OK interrupt!\n"); _rtl_pci_tx_isr(hw, BK_QUEUE); } @@ -843,7 +836,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("BE TX OK interrupt!\n")); + "BE TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, BE_QUEUE); } @@ -851,7 +844,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("VI TX OK interrupt!\n")); + "VI TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VI_QUEUE); } @@ -859,7 +852,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("Vo TX OK interrupt!\n")); + "Vo TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VO_QUEUE); } @@ -868,25 +861,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("CMD TX OK interrupt!\n")); + "CMD TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, TXCMD_QUEUE); } } /*<2> Rx related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("rx descriptor unavailable!\n")); + "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } @@ -1028,7 +1021,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, if (!ring || (unsigned long)ring & 0xFF) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Cannot allocate TX ring (prio = %d)\n", prio)); + "Cannot allocate TX ring (prio = %d)\n", prio); return -ENOMEM; } @@ -1039,8 +1032,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, rtlpci->tx_ring[prio].entries = entries; skb_queue_head_init(&rtlpci->tx_ring[prio].queue); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("queue:%d, ring_addr:%p\n", prio, ring)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", + prio, ring); for (i = 0; i < entries; i++) { nextdescaddress = (u32) dma + @@ -1078,7 +1071,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) if (!rtlpci->rx_ring[rx_queue_idx].desc || (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Cannot allocate RX ring\n")); + "Cannot allocate RX ring\n"); return -ENOMEM; } @@ -1155,10 +1148,12 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, ring->idx = (ring->idx + 1) % ring->entries; } - pci_free_consistent(rtlpci->pdev, - sizeof(*ring->desc) * ring->entries, - ring->desc, ring->dma); - ring->desc = NULL; + if (ring->desc) { + pci_free_consistent(rtlpci->pdev, + sizeof(*ring->desc) * ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; + } } static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) @@ -1182,12 +1177,14 @@ static void _rtl_pci_free_rx_ring(struct rtl_pci *rtlpci) kfree_skb(skb); } - pci_free_consistent(rtlpci->pdev, + if (rtlpci->rx_ring[rx_queue_idx].desc) { + pci_free_consistent(rtlpci->pdev, sizeof(*rtlpci->rx_ring[rx_queue_idx]. desc) * rtlpci->rxringcount, rtlpci->rx_ring[rx_queue_idx].desc, rtlpci->rx_ring[rx_queue_idx].dma); - rtlpci->rx_ring[rx_queue_idx].desc = NULL; + rtlpci->rx_ring[rx_queue_idx].desc = NULL; + } } } @@ -1355,7 +1352,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, u8 temp_one = 1; if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -1388,10 +1385,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, if ((own == 1) && (hw_queue != BEACON_QUEUE)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("No more TX desc@%d, ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); return skb->len; @@ -1426,11 +1422,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, hw_queue != BEACON_QUEUE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - ("less desc left, stop skb_queue@%d, " - "ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); } @@ -1497,7 +1491,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) err = _rtl_pci_init_trx_ring(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("tx ring initialization failed")); + "tx ring initialization failed\n"); return err; } @@ -1519,12 +1513,12 @@ static int rtl_pci_start(struct ieee80211_hw *hw) err = rtlpriv->cfg->ops->hw_init(hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Failed to config hardware!\n")); + "Failed to config hardware!\n"); return err; } rtlpriv->cfg->ops->enable_interrupt(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); rtl_init_rx_config(hw); @@ -1535,7 +1529,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtlpci->up_first_time = false; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); return 0; } @@ -1573,6 +1567,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) rtlpci->driver_is_goingto_unload = true; rtlpriv->cfg->ops->hw_disable(hw); + /* some things are not needed if firmware not available */ + if (!rtlpriv->max_fw_size) + return; rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); @@ -1622,20 +1619,20 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, switch (revisionid) { case RTL_PCI_REVISION_ID_8192PCIE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192 PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192 PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192SE is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Err: Unknown device - " - "vid/did=%x/%x\n", venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; @@ -1646,18 +1643,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192C PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192DE_DID || deviceid == RTL_PCI_8192DE_DID2) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192D PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Err: Unknown device -" - " vid/did=%x/%x\n", venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; } @@ -1665,19 +1662,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { if (revisionid == 0 || revisionid == 1) { if (revisionid == 0) { - RT_TRACE(rtlpriv, COMP_INIT, - DBG_LOUD, ("Find 92DE MAC0.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC0\n"); rtlhal->interfaceindex = 0; } else if (revisionid == 1) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Find 92DE MAC1.\n")); + "Find 92DE MAC1\n"); rtlhal->interfaceindex = 1; } } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Unknown device - " - "VendorID/DeviceID=%x/%x, Revision=%x\n", - venderid, deviceid, revisionid)); + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + venderid, deviceid, revisionid); rtlhal->interfaceindex = 0; } } @@ -1693,8 +1689,8 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Pci Bridge Vendor is found index:" - " %d\n", tmp)); + "Pci Bridge Vendor is found index: %d\n", + tmp); break; } } @@ -1723,23 +1719,21 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("pcidev busnumber:devnumber:funcnumber:" - "vendor:link_ctl %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.busnumber, - pcipriv->ndis_adapter.devnumber, - pcipriv->ndis_adapter.funcnumber, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg)); + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("pci_bridge busnumber:devnumber:funcnumber:vendor:" - "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, - pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch)); + "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.pcibridge_pciehdr_offset, + pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); @@ -1759,18 +1753,17 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = pci_enable_device(pdev); if (err) { - RT_ASSERT(false, - ("%s : Cannot enable new PCI device\n", - pci_name(pdev))); + RT_ASSERT(false, "%s : Cannot enable new PCI device\n", + pci_name(pdev)); return err; } if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { - RT_ASSERT(false, ("Unable to obtain 32bit DMA " - "for consistent allocations\n")); - pci_disable_device(pdev); - return -ENOMEM; + RT_ASSERT(false, + "Unable to obtain 32bit DMA for consistent allocations\n"); + err = -ENOMEM; + goto fail1; } } @@ -1780,7 +1773,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, sizeof(struct rtl_priv), &rtl_ops); if (!hw) { RT_ASSERT(false, - ("%s : ieee80211 alloc failed\n", pci_name(pdev))); + "%s : ieee80211 alloc failed\n", pci_name(pdev)); err = -ENOMEM; goto fail1; } @@ -1791,6 +1784,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv = hw->priv; pcipriv = (void *)rtlpriv->priv; pcipriv->dev.pdev = pdev; + init_completion(&rtlpriv->firmware_loading_complete); /* init cfg & intf_ops */ rtlpriv->rtlhal.interface = INTF_PCI; @@ -1810,8 +1804,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, /* MEM map */ err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { - RT_ASSERT(false, ("Can't obtain PCI resources\n")); - return err; + RT_ASSERT(false, "Can't obtain PCI resources\n"); + goto fail1; } pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); @@ -1823,15 +1817,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, (unsigned long)pci_iomap(pdev, rtlpriv->cfg->bar_id, pmem_len); if (rtlpriv->io.pci_mem_start == 0) { - RT_ASSERT(false, ("Can't map PCI mem\n")); + RT_ASSERT(false, "Can't map PCI mem\n"); + err = -ENOMEM; goto fail2; } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("mem mapped space: start: 0x%08lx len:%08lx " - "flags:%08lx, after map:0x%08lx\n", - pmem_start, pmem_len, pmem_flags, - rtlpriv->io.pci_mem_start)); + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start); /* Disable Clk Request */ pci_write_config_byte(pdev, 0x81, 0); @@ -1841,8 +1835,10 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, pci_write_config_byte(pdev, 0x04, 0x07); /* find adapter */ - if (!_rtl_pci_find_adapter(pdev, hw)) + if (!_rtl_pci_find_adapter(pdev, hw)) { + err = -ENODEV; goto fail3; + } /* Init IO handler */ _rtl_pci_io_handler_init(&pdev->dev, hw); @@ -1851,8 +1847,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); + err = -ENODEV; goto fail3; } @@ -1865,69 +1861,55 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto fail3; } /* Init PCI sw */ err = rtl_pci_init(hw, pdev); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init PCI.\n")); - goto fail3; - } - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't register mac80211 hw.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to init PCI\n"); goto fail3; - } else { - rtlpriv->mac80211.mac80211_registered = 1; } err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("failed to create sysfs device attributes\n")); + "failed to create sysfs device attributes\n"); goto fail3; } - /*init rfkill */ - rtl_init_rfkill(hw); - rtlpci = rtl_pcidev(pcipriv); err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, IRQF_SHARED, KBUILD_MODNAME, hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy))); + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto fail3; - } else { - rtlpci->irq_alloc = 1; } + rtlpci->irq_alloc = 1; - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; fail3: - pci_set_drvdata(pdev, NULL); rtl_deinit_core(hw); _rtl_pci_io_handler_release(hw); - ieee80211_free_hw(hw); if (rtlpriv->io.pci_mem_start != 0) pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); fail2: pci_release_regions(pdev); + complete(&rtlpriv->firmware_loading_complete); fail1: - + if (hw) + ieee80211_free_hw(hw); + pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - return -ENODEV; + return err; } EXPORT_SYMBOL(rtl_pci_probe); @@ -1940,6 +1922,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); struct rtl_mac *rtlmac = rtl_mac(rtlpriv); + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group); diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index ebe0b42c051..241448fc9ed 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, void rtl_pci_disconnect(struct pci_dev *pdev); int rtl_pci_suspend(struct device *dev); int rtl_pci_resume(struct device *dev); - static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 130fdd99d57..5b9c3b5e8c9 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -44,10 +44,11 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) if (is_hal_stop(rtlhal)) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Driver is already down!\n")); + "Driver is already down!\n"); /*<2> Enable Adapter */ - rtlpriv->cfg->ops->hw_init(hw); + if (rtlpriv->cfg->ops->hw_init(hw)) + return 1; RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); /*<3> Enable Interrupt */ @@ -104,8 +105,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, case ERFOFF: - if ((changesource == RF_CHANGE_BY_HW) - && (ppsc->hwradiooff == false)) { + if ((changesource == RF_CHANGE_BY_HW) && !ppsc->hwradiooff) { ppsc->hwradiooff = true; } @@ -120,7 +120,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -176,7 +176,7 @@ void rtl_ips_nic_off_wq_callback(void *data) if (mac->opmode != NL80211_IFTYPE_STATION) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("not station return\n")); + "not station return\n"); return; } @@ -207,7 +207,7 @@ void rtl_ips_nic_off_wq_callback(void *data) (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("IPSEnter(): Turn off RF.\n")); + "IPSEnter(): Turn off RF\n"); ppsc->inactive_pwrstate = ERFOFF; ppsc->in_powersavemode = true; @@ -280,8 +280,7 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) if (ps_timediff < 2000) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Delay enter Fw LPS for DHCP, ARP," - " or EAPOL exchanging state.\n")); + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); return false; } @@ -328,8 +327,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) bool fw_current_inps; if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("FW LPS leave ps_mode:%x\n", - FW_PS_ACTIVE_MODE)); + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); rpwm_val = 0x0C; /* RF on */ fw_pwrmode = FW_PS_ACTIVE_MODE; @@ -347,8 +346,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) } else { if (rtl_get_fwlps_doze(hw)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("FW LPS enter ps_mode:%x\n", - ppsc->fwctrl_psmode)); + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); rpwm_val = 0x02; /* RF off */ fw_current_inps = true; @@ -402,7 +401,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) if (mac->cnt_after_linked >= 2) { if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Enter 802.11 power save mode...\n")); + "Enter 802.11 power save mode...\n"); rtl_lps_set_psmode(hw, EAUTOPS); } @@ -434,7 +433,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Busy Traffic,Leave 802.11 power save..\n")); + "Busy Traffic,Leave 802.11 power save..\n"); rtl_lps_set_psmode(hw, EACTIVE); } @@ -518,8 +517,8 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, " - "m_buffered: %x\n", u_buffed, m_buffed)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); } } @@ -607,8 +606,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) * sleep = dtim_period, that meaons, we should * awake before every dtim */ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("dtim_counter:%x will sleep :%d" - " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv)); + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); /* we tested that 40ms is enough for sw & hw sw delay */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index 84628e6041c..1357856998c 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 539df66dce0..c66f08a0524 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -251,7 +251,7 @@ static void *rtl_rate_alloc_sta(void *ppriv, rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp); if (!rate_priv) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unable to allocate private rc structure\n")); + "Unable to allocate private rc structure\n"); return NULL; } diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h index 4afa2c20adc..4d617616061 100644 --- a/drivers/net/wireless/rtlwifi/rc.h +++ b/drivers/net/wireless/rtlwifi/rc.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index 9fedb1f7091..c1608cddc52 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -398,13 +398,11 @@ int rtl_regd_init(struct ieee80211_hw *hw, rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan; RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", - rtlpriv->regd.country_code)); + "rtl: EEPROM regdomain: 0x%0x\n", rtlpriv->regd.country_code); if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - (KERN_DEBUG "rtl: EEPROM indicates invalid contry code" - "world wide 13 should be used\n")); + "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n"); rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; } @@ -420,8 +418,8 @@ int rtl_regd_init(struct ieee80211_hw *hw, } RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n", - rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1])); + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); @@ -433,7 +431,7 @@ int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); } diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h index d23118938fa..70ef2f418a4 100644 --- a/drivers/net/wireless/rtlwifi/regd.h +++ b/drivers/net/wireless/rtlwifi/regd.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 72a98cab6f6..1208b753f62 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -246,16 +246,15 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); } static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) @@ -313,8 +312,8 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) dm_digtable.backoff_val; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("rssi_val_min = %x backoff_val %x\n", - dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + "rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val); rtl92c_dm_write_dig(hw); } @@ -330,8 +329,8 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) if (mac->opmode == NL80211_IFTYPE_ADHOC) multi_sta = true; - if ((multi_sta == false) || (dm_digtable.cursta_connectctate != - DIG_STA_DISCONNECT)) { + if (!multi_sta || + dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { initialized = false; dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; return; @@ -364,10 +363,9 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("curmultista_connectstate = " - "%x dig_ext_port_stage %x\n", - dm_digtable.curmultista_connectstate, - dm_digtable.dig_ext_port_stage)); + "curmultista_connectstate = %x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage); } static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) @@ -375,10 +373,9 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("presta_connectstate = %x," - " cursta_connectctate = %x\n", - dm_digtable.presta_connectstate, - dm_digtable.cursta_connectctate)); + "presta_connectstate = %x, cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate); if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT @@ -464,11 +461,11 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; } - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n", + dm_digtable.cur_cck_pd_state); - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n", + IS_92C_SERIAL(rtlhal->version)); } static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) @@ -519,10 +516,13 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val); + + dm_digtable.cur_igvalue += 2; + if (dm_digtable.cur_igvalue > 0x3f) + dm_digtable.cur_igvalue = 0x3f; if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, @@ -676,15 +676,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtlpriv->dm.txpower_trackinginit = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + "rtl92c_dm_txpower_tracking_callback_thermalmeter\n"); thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter); rtl92c_phy_ap_calibrate(hw, (thermalvalue - rtlefuse->eeprom_thermalmeter)); @@ -702,10 +701,9 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw ofdm_index_old[0] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx, " - "ofdm_index=0x%x\n", + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", ROFDM0_XATXIQIMBALANCE, - ele_d, ofdm_index_old[0])); + ele_d, ofdm_index_old[0]); break; } } @@ -719,11 +717,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw MASKOFDM_D)) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial pathB ele_d reg0x%x = " - "0x%lx, ofdm_index=0x%x\n", - ROFDM0_XBTXIQIMBALANCE, ele_d, - ofdm_index_old[1])); + DBG_LOUD, + "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1]); break; } } @@ -741,11 +738,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.cck_inch14)); + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); break; } } else { @@ -757,11 +753,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.cck_inch14)); + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); break; } } @@ -790,12 +785,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw (rtlpriv->dm.thermalvalue_iqk - thermalvalue); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", thermalvalue, rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); + delta_iqk); if (delta_lck > 1) { rtlpriv->dm.thermalvalue_lck = thermalvalue; @@ -815,18 +808,15 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); } if (thermalvalue > rtlefuse->eeprom_thermalmeter) { @@ -918,16 +908,13 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], ofdm_index[1], - cck_index)); + "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], cck_index)); + "new OFDM_A_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], cck_index); } } @@ -1085,7 +1072,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtlpriv->dm.thermalvalue = thermalvalue; } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); } @@ -1098,8 +1085,8 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( rtlpriv->dm.txpower_trackinginit = false; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking)); + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); } static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1125,12 +1112,12 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter( rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, 0x60); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); + "Trigger 92S Thermal Meter!!\n"); tm_trigger = 1; return; } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); + "Schedule TxPowerTracking direct call!!\n"); rtl92c_dm_txpower_tracking_directcall(hw); tm_trigger = 0; } @@ -1169,13 +1156,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) if (is_hal_stop(rtlhal)) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver is going to unload\n")); + "<---- driver is going to unload\n"); return; } if (!rtlpriv->dm.useramask) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver does not control rate adaptive mask\n")); + "<---- driver does not control rate adaptive mask\n"); return; } @@ -1210,22 +1197,26 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) p_ra->ratr_state = DM_RATR_STA_LOW; if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI = %ld\n", - rtlpriv->dm.undecorated_smoothed_pwdb)); + "RSSI_LEVEL = %d\n", p_ra->ratr_state); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("PreState = %d, CurState = %d\n", - p_ra->pre_ratr_state, p_ra->ratr_state)); - - rcu_read_lock(); - sta = ieee80211_find_sta(mac->vif, mac->bssid); + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); + + /* Only the PCI card uses sta in the update rate table + * callback routine */ + if (rtlhal->interface == INTF_PCI) { + rcu_read_lock(); + sta = ieee80211_find_sta(mac->vif, mac->bssid); + } rtlpriv->cfg->ops->update_rate_tbl(hw, sta, p_ra->ratr_state); p_ra->pre_ratr_state = p_ra->ratr_state; - rcu_read_unlock(); + if (rtlhal->interface == INTF_PCI) + rcu_read_unlock(); } } } @@ -1316,8 +1307,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) if (((mac->link_state == MAC80211_NOLINK)) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { dm_pstable.rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("Not connected to any\n")); + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); } if (mac->link_state == MAC80211_LINKED) { @@ -1325,22 +1315,22 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) dm_pstable.rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } else { dm_pstable.rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } } else { dm_pstable.rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } if (IS_92C_SERIAL(rtlhal->version)) @@ -1381,7 +1371,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -1394,28 +1384,28 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -1423,18 +1413,18 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index b9736d3e9a3..2178e376188 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 931d97979b0..c20b3c30f62 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,16 +27,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/firmware.h> -#include <linux/export.h> #include "../wifi.h" #include "../pci.h" #include "../base.h" #include "../rtl8192ce/reg.h" #include "../rtl8192ce/def.h" #include "fw_common.h" +#include <linux/export.h> static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) { @@ -172,7 +169,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 *bufferPtr = (u8 *) buffer; - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size); if (IS_CHIP_VER_B(version)) { u32 pageNums, remainSize; @@ -186,7 +183,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, if (pageNums > 4) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 4\n")); + "Page numbers should not greater then 4\n"); } for (page = 0; page < pageNums; page++) { @@ -219,13 +216,12 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", value32); return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; @@ -238,9 +234,8 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); if (value32 & WINTINI_RDY) { RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Polling FW ready success!!" - " REG_MCUFWDL:0x%08x .\n", - value32)); + "Polling FW ready success!! REG_MCUFWDL:0x%08x\n", + value32); return 0; } @@ -249,7 +244,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); + "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", value32); return -EIO; } @@ -262,20 +257,19 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) u32 fwsize; enum version_8192c version = rtlhal->version; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; - pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; pfwdata = (u8 *) rtlhal->pfirmware; fwsize = rtlhal->fwsize; if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Firmware Version(%d), Signature(%#x),Size(%d)\n", + "Firmware Version(%d), Signature(%#x),Size(%d)\n", le16_to_cpu(pfwheader->version), le16_to_cpu(pfwheader->signature), - (uint)sizeof(struct rtl92c_firmware_header))); + (uint)sizeof(struct rtl92c_firmware_header)); pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); fwsize = fwsize - sizeof(struct rtl92c_firmware_header); @@ -287,10 +281,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) if (_rtl92c_fw_free_to_go(hw)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is not ready to run!\n")); + "Firmware is not ready to run!\n"); } else { RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Firmware is ready to run!\n")); + "Firmware is ready to run!\n"); } return 0; @@ -328,22 +322,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, unsigned long flag; u8 idx; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -363,8 +357,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } @@ -388,7 +381,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -398,8 +391,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, wait_h2c_limmit--; if (wait_h2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); break; } @@ -408,14 +401,14 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); } if (!isfw_read) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); + "Write H2C register BOX[%d] fail!!!!! Fw do not read\n", + boxnum); break; } @@ -423,8 +416,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: @@ -493,7 +486,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -504,29 +497,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, rtlhal->last_hmeboxnum = 0; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) { - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); - return; - } - memset(tmp_cmdbuf, 0, 8); memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); @@ -547,7 +533,7 @@ void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) while (u1b_tmp & BIT(2)) { delay--; if (delay == 0) { - RT_ASSERT(false, ("8051 reset fail.\n")); + RT_ASSERT(false, "8051 reset fail\n"); break; } udelay(50); @@ -562,7 +548,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[3] = {0}; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); @@ -570,7 +556,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) ppsc->reg_max_lps_awakeintvl); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode", u1_h2c_set_pwrmode, 3); rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); @@ -780,14 +766,16 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) totalpacketlen = TOTAL_RESERVED_PKT_LEN; RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", &reserved_page_packet[0], totalpacketlen); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); @@ -798,15 +786,14 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); + "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h index cec5a3a1cc5..780ea5b1e24 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c index 605ff191aeb..918b1d129e7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,8 +27,8 @@ * *****************************************************************************/ -#include <linux/module.h> #include "../wifi.h" +#include <linux/module.h> MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 1f07558debf..1eec3a06d1f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -42,16 +42,15 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, - bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, - regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -64,9 +63,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -76,9 +75,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); @@ -86,7 +85,7 @@ EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset) { - RT_ASSERT(false, ("deprecated!\n")); + RT_ASSERT(false, "deprecated!\n"); return 0; } @@ -96,7 +95,7 @@ void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data) { - RT_ASSERT(false, ("deprecated!\n")); + RT_ASSERT(false, "deprecated!\n"); } EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); @@ -114,7 +113,7 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, offset &= 0x3f; newoffset = offset; if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); return 0xFFFFFFFF; } tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); @@ -144,9 +143,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, - retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); @@ -162,16 +160,15 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); return; } offset &= 0x3f; newoffset = offset; data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, - data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); @@ -180,7 +177,7 @@ u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) u32 i; for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) + if ((bitmask >> i) & 0x1) break; } return i; @@ -216,30 +213,30 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } if (rtlphy->rf_type == RF_1T2R) { _rtl92c_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); } if (rtlefuse->autoload_failflag == false) { rtlphy->pwrgroup_cnt = 0; rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw, BASEBAND_CONFIG_PHY_REG); } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, @@ -256,121 +253,51 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); + int index; + + if (regaddr == RTXAGC_A_RATE18_06) + index = 0; + else if (regaddr == RTXAGC_A_RATE54_24) + index = 1; + else if (regaddr == RTXAGC_A_CCK1_MCS32) + index = 6; + else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) + index = 7; + else if (regaddr == RTXAGC_A_MCS03_MCS00) + index = 2; + else if (regaddr == RTXAGC_A_MCS07_MCS04) + index = 3; + else if (regaddr == RTXAGC_A_MCS11_MCS08) + index = 4; + else if (regaddr == RTXAGC_A_MCS15_MCS12) + index = 5; + else if (regaddr == RTXAGC_B_RATE18_06) + index = 8; + else if (regaddr == RTXAGC_B_RATE54_24) + index = 9; + else if (regaddr == RTXAGC_B_CCK1_55_MCS32) + index = 14; + else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) + index = 15; + else if (regaddr == RTXAGC_B_MCS03_MCS00) + index = 10; + else if (regaddr == RTXAGC_B_MCS07_MCS04) + index = 11; + else if (regaddr == RTXAGC_B_MCS11_MCS08) + index = 12; + else if (regaddr == RTXAGC_B_MCS15_MCS12) + index = 13; + else + return; - if (regaddr == RTXAGC_A_RATE18_06) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); - } - if (regaddr == RTXAGC_A_RATE54_24) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); - } - if (regaddr == RTXAGC_A_CCK1_MCS32) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); - } - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); - } - if (regaddr == RTXAGC_A_MCS03_MCS00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); - } - if (regaddr == RTXAGC_A_MCS07_MCS04) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); - } - if (regaddr == RTXAGC_A_MCS11_MCS08) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); - } - if (regaddr == RTXAGC_A_MCS15_MCS12) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); - } - if (regaddr == RTXAGC_B_RATE18_06) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); - } - if (regaddr == RTXAGC_B_RATE54_24) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); - } - if (regaddr == RTXAGC_B_CCK1_55_MCS32) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); - } - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); - } - if (regaddr == RTXAGC_B_MCS03_MCS00) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); - } - if (regaddr == RTXAGC_B_MCS07_MCS04) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); - } - if (regaddr == RTXAGC_B_MCS11_MCS08) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); - } - if (regaddr == RTXAGC_B_MCS15_MCS12) { - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", + rtlphy->pwrgroup_cnt, index, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index]); + if (index == 13) rtlphy->pwrgroup_cnt++; - } } EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset); @@ -389,12 +316,11 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); @@ -402,8 +328,8 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_RXDETECTOR2, MASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) @@ -584,7 +510,7 @@ void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); u8 cckpowerlevel[2], ofdmpowerlevel[2]; - if (rtlefuse->txpwr_fromeprom == false) + if (!rtlefuse->txpwr_fromeprom) return; _rtl92c_get_txpower_index(hw, channel, &cckpowerlevel[0], &ofdmpowerlevel[0]); @@ -615,8 +541,8 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) else ofdmtxpwridx = 0; RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx)); + "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx); for (idx = 0; idx < 14; idx++) { for (rf_path = 0; rf_path < 2; rf_path++) { rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; @@ -710,7 +636,7 @@ void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -732,7 +658,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); + "FALSE driver sleep or unload\n"); rtlphy->set_bwmode_inprogress = false; rtlphy->current_chan_bw = tmp_bw; } @@ -747,7 +673,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) u32 delay; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + "switch to channel%d\n", rtlphy->current_channel); if (is_hal_stop(rtlhal)) return; do { @@ -765,7 +691,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); @@ -780,19 +706,18 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) if (rtlphy->set_bwmode_inprogress) return 0; RT_ASSERT((rtlphy->current_channel <= 14), - ("WIRELESS_MODE_G but channel>14")); + "WIRELESS_MODE_G but channel>14\n"); rtlphy->sw_chnl_inprogress = true; rtlphy->sw_chnl_stage = 0; rtlphy->sw_chnl_step = 0; if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl92c_phy_sw_chnl_callback(hw); RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false schdule workitem\n")); + "sw_chnl_inprogress false schdule workitem\n"); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or" - " unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); rtlphy->sw_chnl_inprogress = false; } return 1; @@ -807,7 +732,7 @@ static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } @@ -853,7 +778,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); + "invalid channel for Zebra: %d\n", channel); _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, @@ -916,7 +841,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -1920,23 +1845,23 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) bool postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); postprocessing = true; break; case IO_CMD_PAUSE_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); postprocessing = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -1947,7 +1872,7 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92c_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); return true; } EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); @@ -1958,8 +1883,8 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; @@ -1973,12 +1898,12 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); } EXPORT_SYMBOL(rtl92c_phy_set_io); @@ -2018,7 +1943,7 @@ void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); + "Switch RF timeout !!!\n"); return; } rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index 9a264c0d612..cec10d69649 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 9fc804d89d6..04c3aef8a4f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 2df33e53e15..27b3af880d9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -54,7 +54,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -67,28 +67,28 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -96,18 +96,18 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 07dd9552e82..26747fa8600 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a3deaefa788..5c4d9bc040f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -141,7 +141,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -207,7 +207,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); @@ -246,8 +246,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -261,8 +261,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -310,8 +310,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -348,8 +348,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -365,14 +365,14 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -507,8 +507,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -530,8 +530,8 @@ static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); + "Failed to polling write LLT done at address %d!\n", + address); status = false; break; } @@ -669,18 +669,15 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) udelay(2); retry = 0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, 0xEC), - bytetmp)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); while ((bytetmp & BIT(0)) && retry < 1000) { retry++; udelay(50); bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, - 0xEC), - bytetmp)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); udelay(50); } @@ -696,7 +693,7 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) rtl_write_word(rtlpriv, REG_CR, 0x2ff); - if (_rtl92ce_llt_table_init(hw) == false) + if (!_rtl92ce_llt_table_init(hw)) return false; rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); @@ -864,13 +861,13 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) u8 sec_reg_value; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open " - "hw encryption\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); return; } @@ -886,7 +883,7 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -909,8 +906,8 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtlpci->being_init_adapter = true; rtlpriv->intf_ops->disable_aspm(hw); rtstatus = _rtl92ce_init_mac(hw); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; return err; } @@ -918,13 +915,9 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) err = rtl92c_download_fw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; - rtlhal->fw_ready = false; return err; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; @@ -968,12 +961,12 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) tmp_u1b = efuse_read_1byte(hw, 0x1FA); if (!(tmp_u1b & BIT(0))) { rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); } if (!(tmp_u1b & BIT(1)) && is92c) { rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path B\n"); } if (!(tmp_u1b & BIT(4))) { @@ -982,7 +975,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); udelay(10); rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); } rtl92c_dm_init(hw); rtlpci->being_init_adapter = false; @@ -995,6 +988,7 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); enum version_8192c version = VERSION_UNKNOWN; u32 value32; + const char *versionid; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (value32 & TRP_VAUX_EN) { @@ -1007,27 +1001,25 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) switch (version) { case VERSION_B_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + versionid = "B_CHIP_92C"; break; case VERSION_B_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_88C.\n")); + versionid = "B_CHIP_88C"; break; case VERSION_A_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_92C.\n")); + versionid = "A_CHIP_92C"; break; case VERSION_A_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_88C.\n")); + versionid = "A_CHIP_88C"; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Chip Version ID: Unknown. Bug?\n")); + versionid = "Unknown. Bug?"; break; } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + switch (version & 0x3) { case CHIP_88C: rtlphy->rf_type = RF_1T1R; @@ -1041,13 +1033,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) default: rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("ERROR RF_Type is set!!")); + "ERROR RF_Type is set!!\n"); break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); return version; } @@ -1069,8 +1060,8 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, _rtl92ce_disable_bcn_sub_func(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: " - "No such media status(%x).\n", type)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); } switch (type) { @@ -1078,27 +1069,27 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, bt_msr |= MSR_NOLINK; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1126,7 +1117,7 @@ void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (®_rcr)); _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); - } else if (check_bssid == false) { + } else if (!check_bssid) { reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); _rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0); rtlpriv->cfg->ops->set_hw_reg(hw, @@ -1171,7 +1162,7 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } @@ -1199,7 +1190,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 u1b_tmp; u32 u4b_tmp; @@ -1210,7 +1200,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) rtl92c_firmware_selfreset(hw); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); @@ -1300,7 +1290,7 @@ void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) u16 bcn_interval = mac->beacon_interval; RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + "beacon_interval:%d\n", bcn_interval); rtl92ce_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); rtl92ce_enable_interrupt(hw); @@ -1312,8 +1302,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1367,25 +1357,24 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, - rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { @@ -1416,11 +1405,11 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } @@ -1457,13 +1446,13 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } @@ -1502,27 +1491,27 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); if (!autoload_fail) rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); else rtlefuse->eeprom_regulatory = 0; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); if (!autoload_fail) { rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; @@ -1531,10 +1520,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; } - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); if (!autoload_fail) tempval = hwinfo[EEPROM_THERMAL_METER]; @@ -1547,7 +1535,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); } static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) @@ -1567,19 +1555,19 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!"); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1591,8 +1579,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); _rtl92ce_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, @@ -1608,7 +1595,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1662,7 +1649,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) break; } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); } void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) @@ -1679,22 +1666,22 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92ce_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } _rtl92ce_hal_customized_behavior(hw); } @@ -1790,8 +1777,8 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -1919,16 +1906,15 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, break; } RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x\n", ratr_bitmap)); + "ratr_bitmap :%x\n", ratr_bitmap); *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | (ratr_index << 28)); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); if (macid != 0) @@ -1994,15 +1980,14 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); + "GPIOChangeRF - HW Radio ON, RF ON\n"); e_rfpowerstate_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; - } else if ((ppsc->hwradiooff == false) - && (e_rfpowerstate_toset == ERFOFF)) { + } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); e_rfpowerstate_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2053,7 +2038,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2081,8 +2066,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2100,9 +2085,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, - ("Can not find free hw" - " security cam entry\n")); + DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2116,31 +2100,31 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2149,7 +2133,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index 07dbe3e340a..52a3aea9b3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 28a1a707d09..8283e9b2763 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -45,8 +45,8 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -62,7 +62,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -74,8 +74,8 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -97,7 +97,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -145,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw, ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", + ledaction); _rtl92ce_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 7dfccea2095..c5761066d38 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 3b585aadabf..88deae67cc1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -47,9 +47,9 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); @@ -67,9 +67,8 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -121,8 +120,8 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, u32 original_value, bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); @@ -153,10 +152,9 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), " - "rfpath(%#x)\n", regaddr, - bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) @@ -166,11 +164,10 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = MAC_2T_ARRAYLENGTH; ptrarray = RTL8192CEMAC_2T_ARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -215,10 +212,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -226,10 +222,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_array_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); } } return true; @@ -269,7 +264,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -291,20 +286,20 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_arraylen = RADIOB_2TARRAYLENGTH; radiob_array_table = RTL8192CE_RADIOB_2TARRAY; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); } else { radioa_arraylen = RADIOA_1TARRAYLENGTH; radioa_array_table = RTL8192CE_RADIOA_1TARRAY; radiob_arraylen = RADIOB_1TARRAYLENGTH; radiob_array_table = RTL8192CE_RADIOB_1TARRAY; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { @@ -352,11 +347,11 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -371,10 +366,9 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; @@ -398,7 +392,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } @@ -423,12 +417,12 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) @@ -499,7 +493,7 @@ static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); + "Switch RF timeout !!!\n"); return; } rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); @@ -526,18 +520,17 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) - && (InitializeCount < 10)); + } while (!rtstatus && (InitializeCount < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ce_phy_set_rf_on(hw); } @@ -553,7 +546,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -578,35 +571,33 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92ce_phy_set_rf_sleep(hw); break; } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index be2c92adef3..d5e3b704f93 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index ba5ff0411f0..e4d738f6166 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -1190,7 +1190,6 @@ #define USB_AGG_EN BIT(3) -#define MAC_ADDR_LEN 6 #define LAST_ENTRY_OF_TX_PKT_BUFFER 255 #define POLLING_LLT_THRESHOLD 20 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index d3b01e6023b..54c7614958a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -56,7 +56,7 @@ void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -123,8 +123,8 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; @@ -133,22 +133,22 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, @@ -171,8 +171,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase0 << 8) | powerBase0; *(ofdmbase + i) = powerBase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { @@ -187,8 +187,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, *(mcsbase + i) = powerBase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -215,9 +215,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 1: if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { @@ -225,9 +224,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 40MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 40MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); } else { if (rtlphy->pwrgroup_cnt == 1) chnlgroup = 0; @@ -249,9 +247,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); } break; case 2: @@ -259,27 +256,24 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Better regulatory, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht40[rf][channel - - 1])); + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht20[rf][channel - - 1])); + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -311,15 +305,15 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Customer, writeVal rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; default: chnlgroup = 0; @@ -329,9 +323,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeVal " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance, writeVal rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; } @@ -383,7 +376,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); + "Set 0x%x = %08x\n", regoffset, writeVal); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || @@ -510,14 +503,14 @@ static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw) break; } - if (rtstatus != true) { + if (!rtstatus) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!\n", rfpath); return false; } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 39ff0368598..6c8d56efcea 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 89ef6982ce5..2c3b73366cd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,9 +27,6 @@ * *****************************************************************************/ -#include <linux/vmalloc.h> -#include <linux/module.h> - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -43,6 +40,8 @@ #include "trx.h" #include "led.h" +#include <linux/module.h> + static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -92,9 +91,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) int err; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - char *fw_name = NULL; rtl8192ce_bt_reg_init(hw); @@ -159,33 +156,27 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } /* request fw */ if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && !IS_92C_SERIAL(rtlhal->version)) - fw_name = "rtlwifi/rtl8192cfwU.bin"; + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - fw_name = "rtlwifi/rtl8192cfwU_B.bin"; - else - fw_name = rtlpriv->cfg->fw_name; - err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + + rtlpriv->max_fw_size = 0x4000; + pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); - return 1; - } - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); - release_firmware(firmware); + "Failed to request firmware!\n"); return 1; } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); return 0; } @@ -404,7 +395,7 @@ static int __init rtl92ce_module_init(void) ret = pci_register_driver(&rtl92ce_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index b7dc3263e43..d2367a5d0cf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c index ba938b91aa6..752f943a84a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h index 3a6e8b6aeee..8b79161f71b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 4fb5ae24dee..37b13636a77 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -725,7 +725,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -763,7 +763,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(pdesc, 1); } - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, @@ -821,8 +821,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", - pdesc, TX_DESC_SIZE); + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); } void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) @@ -837,8 +836,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -857,8 +856,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -877,8 +876,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -891,8 +890,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_RX_DESC_PKT_LEN(pdesc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index c8977a50ca3..efb9ab27040 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h index d097efb1e71..f916555e631 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index f311baee668..6fd39eaf361 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -52,7 +52,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -65,28 +65,28 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -94,18 +94,18 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h index 7f966c666b5..d947e7d350b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 124cf633861..0c74d4f2eeb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../efuse.h" #include "../base.h" @@ -162,24 +160,24 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { index = _rtl92c_get_chnl_group((u8) i); @@ -205,11 +203,10 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, } for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } for (i = 0; i < 3; i++) { @@ -242,13 +239,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, & 0xf0) >> 4); } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } for (i = 0; i < 14; i++) { @@ -277,26 +274,26 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); if (!autoload_fail) rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); else rtlefuse->eeprom_regulatory = 0; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); if (!autoload_fail) { rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; @@ -305,9 +302,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); if (!autoload_fail) tempval = hwinfo[EEPROM_THERMAL_METER]; else @@ -320,7 +317,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->apk_thermalmeterignore = true; rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); } static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) @@ -340,144 +337,8 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) if (IS_HIGHT_PA(rtlefuse->board_type)) rtlefuse->external_pa = 1; pr_info("Board Type %x\n", rtlefuse->board_type); - -#ifdef CONFIG_ANTENNA_DIVERSITY - /* Antenna Diversity setting. */ - if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */ - rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3; - else - rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */ - - pr_info("Antenna Config %x\n", rtl_efuse->antenna_cfg); -#endif -} - -#ifdef CONFIG_BT_COEXIST -static void _update_bt_param(_adapter *padapter) -{ - struct btcoexist_priv *pbtpriv = &(padapter->halpriv.bt_coexist); - struct registry_priv *registry_par = &padapter->registrypriv; - if (2 != registry_par->bt_iso) { - /* 0:Low, 1:High, 2:From Efuse */ - pbtpriv->BT_Ant_isolation = registry_par->bt_iso; - } - if (registry_par->bt_sco == 1) { - /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, - * 5.OtherBusy */ - pbtpriv->BT_Service = BT_OtherAction; - } else if (registry_par->bt_sco == 2) { - pbtpriv->BT_Service = BT_SCO; - } else if (registry_par->bt_sco == 4) { - pbtpriv->BT_Service = BT_Busy; - } else if (registry_par->bt_sco == 5) { - pbtpriv->BT_Service = BT_OtherBusy; - } else { - pbtpriv->BT_Service = BT_Idle; - } - pbtpriv->BT_Ampdu = registry_par->bt_ampdu; - pbtpriv->bCOBT = _TRUE; - pbtpriv->BtEdcaUL = 0; - pbtpriv->BtEdcaDL = 0; - pbtpriv->BtRssiState = 0xff; - pbtpriv->bInitSet = _FALSE; - pbtpriv->bBTBusyTraffic = _FALSE; - pbtpriv->bBTTrafficModeSet = _FALSE; - pbtpriv->bBTNonTrafficModeSet = _FALSE; - pbtpriv->CurrentState = 0; - pbtpriv->PreviousState = 0; - pr_info("BT Coexistance = %s\n", - (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable"); - if (pbtpriv->BT_Coexist) { - if (pbtpriv->BT_Ant_Num == Ant_x2) - pr_info("BlueTooth BT_Ant_Num = Antx2\n"); - else if (pbtpriv->BT_Ant_Num == Ant_x1) - pr_info("BlueTooth BT_Ant_Num = Antx1\n"); - switch (pbtpriv->BT_CoexistType) { - case BT_2Wire: - pr_info("BlueTooth BT_CoexistType = BT_2Wire\n"); - break; - case BT_ISSC_3Wire: - pr_info("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); - break; - case BT_Accel: - pr_info("BlueTooth BT_CoexistType = BT_Accel\n"); - break; - case BT_CSR_BC4: - pr_info("BlueTooth BT_CoexistType = BT_CSR_BC4\n"); - break; - case BT_CSR_BC8: - pr_info("BlueTooth BT_CoexistType = BT_CSR_BC8\n"); - break; - case BT_RTL8756: - pr_info("BlueTooth BT_CoexistType = BT_RTL8756\n"); - break; - default: - pr_info("BlueTooth BT_CoexistType = Unknown\n"); - break; - } - pr_info("BlueTooth BT_Ant_isolation = %d\n", - pbtpriv->BT_Ant_isolation); - switch (pbtpriv->BT_Service) { - case BT_OtherAction: - pr_info("BlueTooth BT_Service = BT_OtherAction\n"); - break; - case BT_SCO: - pr_info("BlueTooth BT_Service = BT_SCO\n"); - break; - case BT_Busy: - pr_info("BlueTooth BT_Service = BT_Busy\n"); - break; - case BT_OtherBusy: - pr_info("BlueTooth BT_Service = BT_OtherBusy\n"); - break; - default: - pr_info("BlueTooth BT_Service = BT_Idle\n"); - break; - } - pr_info("BT_RadioSharedType = 0x%x\n", - pbtpriv->BT_RadioSharedType); - } } -#define GET_BT_COEXIST(priv) (&priv->bt_coexist) - -static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw, - u8 *contents, - bool bautoloadfailed); -{ - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); - bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID); - struct btcoexist_priv *pbtpriv = &pHalData->bt_coexist; - u8 rf_opt4; - - _rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv)); - if (AutoloadFail) { - pbtpriv->BT_Coexist = _FALSE; - pbtpriv->BT_CoexistType = BT_2Wire; - pbtpriv->BT_Ant_Num = Ant_x2; - pbtpriv->BT_Ant_isolation = 0; - pbtpriv->BT_RadioSharedType = BT_Radio_Shared; - return; - } - if (isNormal) { - if (pHalData->BoardType == BOARD_USB_COMBO) - pbtpriv->BT_Coexist = _TRUE; - else - pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] & - 0x20) >> 5); /* bit[5] */ - rf_opt4 = PROMContent[EEPROM_RF_OPT4]; - pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */ - pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */ - pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */ - pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */ - } else { - pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ? - _TRUE : _FALSE; - } - _update_bt_param(Adapter); -} -#endif - static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -494,17 +355,17 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0])); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } if (rtlefuse->autoload_failflag) @@ -518,16 +379,15 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag, hwinfo); rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]); rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (" VID = 0x%02x PID = 0x%02x\n", - rtlefuse->eeprom_vid, rtlefuse->eeprom_did)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n", + rtlefuse->eeprom_vid, rtlefuse->eeprom_did); rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_version = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]); rtlefuse->txpwr_fromeprom = true; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); if (rtlhal->oem_id == RT_CID_DEFAULT) { switch (rtlefuse->eeprom_oemid) { case EEPROM_CID_DEFAULT: @@ -554,10 +414,6 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) } } _rtl92cu_read_board_type(hw, hwinfo); -#ifdef CONFIG_BT_COEXIST - _rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo, - rtlefuse->autoload_failflag); -#endif } static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) @@ -579,8 +435,8 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) default: break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); } void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) @@ -596,11 +452,11 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", - (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n", + tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE"); rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", - (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n", + tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!"); _rtl92cu_read_adapter_info(hw); _rtl92cu_hal_customized_behavior(hw); return; @@ -618,13 +474,12 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) do { if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Autoload Done!\n")); + "Autoload Done!\n"); break; } if (pollingCount++ > 100) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Failed to polling REG_APS_FSMCO[PFM_ALDN]" - " done!\n")); + "Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n"); return -ENODEV; } } while (true); @@ -639,8 +494,8 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) value8 |= LDV12_EN; rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", - value8)); + " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n", + value8); udelay(100); value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); value8 &= ~ISO_MD2PP; @@ -658,8 +513,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) } if (pollingCount++ > 100) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]" - " done!\n")); + "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); return -ENODEV; } } while (true); @@ -877,8 +731,8 @@ static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw, hiQ = QUEUE_HIGH; } _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Tx queue select :0x%02x..\n", queue_sel)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n", + queue_sel); } static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw, @@ -937,8 +791,8 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, break; } rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Tx queue select :0x%02x..\n", hq_sele)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n", + hq_sele); } static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, @@ -998,7 +852,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init power on!\n")); + "Failed to init power on!\n"); return err; } if (!wmm_enable) { @@ -1010,7 +864,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw) } if (false == rtl92c_init_llt_table(hw, boundary)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init LLT Table!\n")); + "Failed to init LLT Table!\n"); return -EINVAL; } _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, @@ -1043,12 +897,12 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtlpriv); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open sw encryption\n")); + "not open sw encryption\n"); return; } sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; @@ -1059,8 +913,8 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) if (IS_NORMAL_CHIP(rtlhal->version)) sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); } @@ -1111,34 +965,6 @@ static void _InitPABias(struct ieee80211_hw *hw) } } -static void _InitAntenna_Selection(struct ieee80211_hw *hw) -{ -#ifdef CONFIG_ANTENNA_DIVERSITY - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (pHalData->AntDivCfg == 0) - return; - - if (rtlphy->rf_type == RF_1T1R) { - rtl_write_dword(rtlpriv, REG_LEDCFG0, - rtl_read_dword(rtlpriv, - REG_LEDCFG0)|BIT(23)); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) == - Antenna_A) - pHalData->CurAntenna = Antenna_A; - else - pHalData->CurAntenna = Antenna_B; - } -#endif -} - -static void _dump_registers(struct ieee80211_hw *hw) -{ -} - static void _update_mac_setting(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1163,18 +989,15 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; err = _rtl92cu_init_mac(hw); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); return err; } err = rtl92c_download_fw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; - rtlhal->fw_ready = false; return err; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; /* h2c */ _rtl92cu_phy_param_tab_init(hw); @@ -1209,10 +1032,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) } _rtl92cu_hw_configure(hw); _InitPABias(hw); - _InitAntenna_Selection(hw); _update_mac_setting(hw); rtl92c_dm_init(hw); - _dump_registers(hw); return err; } @@ -1270,24 +1091,21 @@ static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { /* reset MCU ready status */ rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); - if (rtlhal->fw_ready) { - /* 8051 reset by self */ - rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); - while ((retry_cnts++ < 100) && - (FEN_CPUEN & rtl_read_word(rtlpriv, - REG_SYS_FUNC_EN))) { - udelay(50); - } - if (retry_cnts >= 100) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("#####=> 8051 reset failed!.." - ".......................\n");); - /* if 8051 reset fail, reset MAC. */ - rtl_write_byte(rtlpriv, - REG_SYS_FUNC_EN + 1, - 0x50); - udelay(100); - } + /* 8051 reset by self */ + rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); + while ((retry_cnts++ < 100) && + (FEN_CPUEN & rtl_read_word(rtlpriv, + REG_SYS_FUNC_EN))) { + udelay(50); + } + if (retry_cnts >= 100) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "#####=> 8051 reset failed!.........................\n"); + /* if 8051 reset fail, reset MAC. */ + rtl_write_byte(rtlpriv, + REG_SYS_FUNC_EN + 1, + 0x50); + udelay(100); } } /* Reset MAC and Enable 8051 */ @@ -1495,35 +1313,36 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw, _rtl92cu_resume_tx_beacon(hw); _rtl92cu_disable_bcn_sub_func(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_" - "STATUS:No such media status(%x).\n", type)); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n", + type); } switch (type) { case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= MSR_NOLINK; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); goto error_out; } rtl_write_byte(rtlpriv, (MSR), bt_msr); @@ -1684,8 +1503,8 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) value32 |= TSFRST; rtl_write_dword(rtlpriv, REG_TCR, value32); RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD, - ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", - value32)); + "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", + value32); /* TODO: Modify later (Find the right parameters) * NOTE: Fix test chip's bug (about contention windows's randomness) */ if ((mac->opmode == NL80211_IFTYPE_ADHOC) || @@ -1702,8 +1521,8 @@ void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u16 bcn_interval = mac->beacon_interval; - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", + bcn_interval); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); } @@ -1767,7 +1586,7 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -1827,8 +1646,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SIFS\n")); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n"); break; } case HW_VAR_SLOT_TIME:{ @@ -1837,7 +1655,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_SLOT, val[0]); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); if (QOS_MODE) { for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, @@ -1901,8 +1719,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) min_spacing_to_set); *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); } @@ -1916,8 +1734,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg &= 0x07; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); break; @@ -1950,8 +1768,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) p_regtoset[index]); } RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -1969,8 +1787,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) AC_PARAM_ECW_MAX_OFFSET); u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("queue:%x, ac_param:%x\n", e_aci, - u4b_ac_param)); + "queue:%x, ac_param:%x\n", + e_aci, u4b_ac_param); switch (e_aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, @@ -1989,8 +1807,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u4b_ac_param); break; default: - RT_ASSERT(false, ("SetHwReg8185(): invalid" - " aci: %d !\n", e_aci)); + RT_ASSERT(false, + "SetHwReg8185(): invalid aci: %d !\n", + e_aci); break; } if (rtlusb->acm_method != eAcmWay2_SW) @@ -2020,8 +1839,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -2037,13 +1856,13 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -2051,7 +1870,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); mac->rx_conf = ((u32 *) (val))[0]; RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, - ("### Set RCR(0x%08x) ###\n", mac->rx_conf)); + "### Set RCR(0x%08x) ###\n", mac->rx_conf); break; } case HW_VAR_RETRY_LIMIT:{ @@ -2060,8 +1879,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_word(rtlpriv, REG_RL, retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT); - RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R" - "ETRY_LIMIT(0x%08x)\n", retry_limit)); + RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, + "Set HW_VAR_RETRY_LIMIT(0x%08x)\n", + retry_limit); break; } case HW_VAR_DUAL_TSF_RST: @@ -2165,8 +1985,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -2239,8 +2059,8 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, (shortgi_rate << 4) | (shortgi_rate); } rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv, - REG_ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) @@ -2344,17 +2164,16 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) ratr_bitmap &= 0x0f0ff0ff; break; } - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n", - ratr_bitmap)); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", + ratr_bitmap); *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); } @@ -2404,7 +2223,7 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) e_rfpowerstate_toset = (u1tmp & BIT(7)) ? ERFOFF : ERFON; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp)); + "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp); } else { rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, @@ -2413,27 +2232,26 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("GPIO_IN=%02x\n", u1tmp)); + "GPIO_IN=%02x\n", u1tmp); } - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n", - e_rfpowerstate_toset)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n", + e_rfpowerstate_toset); } if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW " - "Radio ON, RF ON\n")); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio ON, RF ON\n"); ppsc->hwradiooff = false; actuallyset = true; } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW" - " Radio OFF\n")); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio OFF\n"); ppsc->hwradiooff = true; actuallyset = true; } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , - ("pHalData->bHwRadioOff and eRfPowerStateToSet do not" - " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet " - "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n", + ppsc->hwradiooff, e_rfpowerstate_toset); } if (actuallyset) { ppsc->hwradiooff = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 32f85cba106..f41a3aa4a26 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 2ff9d8314e7..75a2deb23af 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -47,8 +47,8 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -62,7 +62,7 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -74,8 +74,8 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -95,7 +95,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -136,7 +136,6 @@ void rtl92cu_led_control(struct ieee80211_hw *hw, ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92cu_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h index decaee4d1eb..0f372278b7a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 9e0c8fcdf90..025bdc2eba4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -27,10 +27,6 @@ * ****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> - #include "../wifi.h" #include "../pci.h" #include "../usb.h" @@ -44,6 +40,8 @@ #include "mac.h" #include "trx.h" +#include <linux/module.h> + /* macro to shorten lines */ #define LINK_Q ui_link_quality @@ -57,6 +55,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); enum version_8192c chip_version = VERSION_UNKNOWN; + const char *versionid; u32 value32; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); @@ -84,88 +83,69 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) } } rtlhal->version = (enum version_8192c)chip_version; - pr_info("rtl8192cu: Chip version 0x%x\n", chip_version); + pr_info("Chip version 0x%x\n", chip_version); switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + versionid = "NORMAL_B_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n")); + versionid = "NORMAL_TSMC_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n")); + versionid = "NORMAL_TSMC_CHIP_88C"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i" - "92C_1T2R_A_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_" - "92C_A_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_92C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_88C_A_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_88C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_92C_1T2R_B_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_92C_B_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_92C_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_88C_B_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_88C_B_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMA_UMC_CHIP" - "_8723_1T1R_A_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMA_UMC_CHIP" - "_8723_1T1R_B_CUT.\n")); + versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT"; break; case VERSION_TEST_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_TEST_CHIP_92C.\n")); + versionid = "TEST_CHIP_92C"; break; case VERSION_TEST_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_TEST_CHIP_88C.\n")); + versionid = "TEST_CHIP_88C"; break; default: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: ???????????????.\n")); + versionid = "UNKNOWN"; break; } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + if (IS_92C_SERIAL(rtlhal->version)) rtlphy->rf_type = (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; else rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); if (get_rf_type(rtlphy) == RF_1T1R) rtlpriv->dm.rfpath_rxenable[0] = true; else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); } /** @@ -192,9 +172,8 @@ bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) break; if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at" - " address %d! _LLT_OP_VALUE(%x)\n", - address, _LLT_OP_VALUE(value))); + "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n", + address, _LLT_OP_VALUE(value)); status = false; break; } @@ -272,7 +251,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); @@ -298,7 +277,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("iillegal switch case\n")); + "illegal switch case\n"); enc_algo = CAM_TKIP; break; } @@ -317,26 +296,26 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry\n")); + "delete one entry\n"); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -345,7 +324,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, @@ -421,8 +400,8 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) AC_PARAM_ECW_MAX_OFFSET; u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) << AC_PARAM_TXOP_OFFSET; - RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, - ("queue:%x, ac_param:%x\n", aci, u4b_ac_param)); + RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, "queue:%x, ac_param:%x\n", + aci, u4b_ac_param); switch (aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); @@ -437,7 +416,7 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } @@ -453,14 +432,14 @@ void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr) for (i = 0 ; i < ETH_ALEN ; i++) rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-" - "%02X-%02X-%02X\n", - rtl_read_byte(rtlpriv, REG_MACID), - rtl_read_byte(rtlpriv, REG_MACID+1), - rtl_read_byte(rtlpriv, REG_MACID+2), - rtl_read_byte(rtlpriv, REG_MACID+3), - rtl_read_byte(rtlpriv, REG_MACID+4), - rtl_read_byte(rtlpriv, REG_MACID+5))); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, + "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", + rtl_read_byte(rtlpriv, REG_MACID), + rtl_read_byte(rtlpriv, REG_MACID+1), + rtl_read_byte(rtlpriv, REG_MACID+2), + rtl_read_byte(rtlpriv, REG_MACID+3), + rtl_read_byte(rtlpriv, REG_MACID+4), + rtl_read_byte(rtlpriv, REG_MACID+5)); } void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size) @@ -478,26 +457,26 @@ int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) case NL80211_IFTYPE_UNSPECIFIED: value = NT_NO_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: value = NT_LINK_AD_HOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: value = NT_LINK_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: value = NT_AS_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return -EOPNOTSUPP; } rtl_write_byte(rtlpriv, (REG_CR + 2), value); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h index 626d88e88e2..bf53652e4ed 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index e49cf2244c7..34e56308301 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -44,9 +44,9 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); if (rtlphy->rf_mode != RF_OP_BY_FW) { original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); @@ -57,9 +57,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -72,8 +71,8 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, u32 original_value, bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); if (rtlphy->rf_mode != RF_OP_BY_FW) { if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92c_phy_rf_serial_read(hw, @@ -97,9 +96,9 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, } _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); } - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) @@ -152,11 +151,10 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = rtlphy->hwparam_tables[MAC_REG].length ; ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -202,10 +200,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -213,10 +210,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_array_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); } } return true; @@ -255,7 +251,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -277,20 +273,20 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); } else { radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { @@ -338,11 +334,11 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -357,10 +353,9 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; return; @@ -381,7 +376,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } switch (rtlphy->current_chan_bw) { @@ -403,12 +398,12 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } void rtl92cu_bb_block_on(struct ieee80211_hw *hw) @@ -480,18 +475,16 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) - && (InitializeCount < 10)); + } while (!rtstatus && (InitializeCount < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ce_phy_set_rf_on(hw); } @@ -513,27 +506,25 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] " - "=%d before doze!\n", (i + 1), - queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, + queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -557,33 +548,30 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92c_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h index ff81a61729d..42b06866048 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h index 7f1be614c99..8b81465c629 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1e851aae58d..506b9a078ed 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -56,7 +56,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -140,26 +140,26 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; if (mac->mode == WIRELESS_MODE_B) tmpval = tmpval & 0xff00ffff; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, @@ -181,8 +181,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase0 << 8) | powerBase0; *(ofdmbase + i) = powerBase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { @@ -194,8 +194,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; *(mcsbase + i) = powerBase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -219,8 +219,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance,writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance,writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 1: if (rtlphy->pwrgroup_cnt == 1) @@ -244,32 +244,31 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 2: writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory,writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Better regulatory,writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHzrf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 40MHzrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht40[rf] - [channel - 1])); + [channel - 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht20[rf] - [channel - 1])); + [channel - 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -297,22 +296,22 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[2] << 16) | (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Customer, writeVal rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; default: chnlgroup = 0; writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " - "performance, writeValrf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeValrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; } if (rtlpriv->dm.dynamic_txhighpower_lvl == @@ -365,7 +364,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, regoffset = regoffset_b[index]; rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); + "Set 0x%x = %08x\n", regoffset, writeVal); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12)) || @@ -480,13 +479,13 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) BRFSI_RFENV << 16, u4_regvalue); break; } - if (rtstatus != true) { + if (!rtstatus) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!", rfpath); goto phy_rf_cfg_fail; } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; phy_rf_cfg_fail: return rtstatus; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 500a2094b6b..090fd33a158 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 6d2ca773bbc..82c85286ab2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -41,7 +41,6 @@ #include "trx.h" #include "led.h" #include "hw.h" -#include <linux/vmalloc.h> #include <linux/module.h> MODULE_AUTHOR("Georgia <georgia@realtek.com>"); @@ -54,7 +53,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - const struct firmware *firmware; int err; rtlpriv->dm.dm_initialgain_enable = true; @@ -62,29 +60,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->dm.disable_framebursting = false; rtlpriv->dm.thermalvalue = 0; rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; - rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } - /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); - return 1; - } - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); + + pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0x4000; + err = request_firmware_nowait(THIS_MODULE, 1, + rtlpriv->cfg->fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h index 43b1177924a..a1310abd0d5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c index d57ef5e88a9..966be519edb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h index c3d5cd826cf..4b020e9e30b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index b3cc7b94999..21bc827c5fa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -108,7 +108,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, if (bwificfg) { /* for WMM */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB Chip-B & WMM Setting.....\n")); + "USB Chip-B & WMM Setting.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 2; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -118,7 +118,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, ep_map->ep_mapping[RTL_TXQ_HI] = 2; } else { /* typical setting */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB typical Setting.....\n")); + "USB typical Setting.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 3; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 2; @@ -135,7 +135,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, struct rtl_priv *rtlpriv = rtl_priv(hw); if (bwificfg) { /* for WMM */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB 3EP Setting for WMM.....\n")); + "USB 3EP Setting for WMM.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 5; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -145,7 +145,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, ep_map->ep_mapping[RTL_TXQ_HI] = 2; } else { /* typical setting */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB 3EP Setting for typical.....\n")); + "USB 3EP Setting for typical.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 5; ep_map->ep_mapping[RTL_TXQ_BK] = 5; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -244,8 +244,8 @@ u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) break; default: hw_queue_index = RTL_TXQ_BE; - RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", - mac80211_queue_index)); + RT_ASSERT(false, "QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index); break; } out: @@ -270,23 +270,23 @@ static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw, case 0: /* VO */ qsel = QSLT_VO; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("VO queue, set qsel = 0x%x\n", QSLT_VO)); + "VO queue, set qsel = 0x%x\n", QSLT_VO); break; case 1: /* VI */ qsel = QSLT_VI; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("VI queue, set qsel = 0x%x\n", QSLT_VI)); + "VI queue, set qsel = 0x%x\n", QSLT_VI); break; case 3: /* BK */ qsel = QSLT_BK; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("BK queue, set qsel = 0x%x\n", QSLT_BK)); + "BK queue, set qsel = 0x%x\n", QSLT_BK); break; case 2: /* BE */ default: qsel = QSLT_BE; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("BE queue, set qsel = 0x%x\n", QSLT_BE)); + "BE queue, set qsel = 0x%x\n", QSLT_BE); break; } out: @@ -422,17 +422,17 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) bv = ieee80211_is_probe_resp(fc); if (bv) RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Got probe response frame.\n")); + "Got probe response frame\n"); if (ieee80211_is_beacon(fc)) - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Got beacon frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n"); if (ieee80211_is_data(fc)) - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:" - "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1], - (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4], - (u32)hdr->addr1[5])); + "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n", + fc, + (u32)hdr->addr1[0], (u32)hdr->addr1[1], + (u32)hdr->addr1[2], (u32)hdr->addr1[3], + (u32)hdr->addr1[4], (u32)hdr->addr1[5]); memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); ieee80211_rx_irqsafe(hw, skb); } @@ -594,7 +594,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(txdesc, 1); SET_TX_DESC_HTC(txdesc, 1); } @@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(txdesc, 1); _rtl_fill_usb_tx_desc(txdesc); _rtl_tx_desc_checksum(txdesc); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n"); } void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, @@ -677,7 +677,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, SET_TX_DESC_HWSEQ_EN(pdesc, 1); SET_TX_DESC_PKT_ID(pdesc, 8); } - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content", pdesc, RTL_TX_DESC_SIZE); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index 53de5f66e24..332b06e78b0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h index 94630477174..eafdf76ed64 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 3cd0736fe8e..4737018c9da 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -246,23 +246,21 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, " - "Cnt_SB_Search_fail = %x\n", + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n", falsealm_cnt->cnt_fast_fsync_fail, - falsealm_cnt->cnt_sb_search_fail)); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, " - "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, " - "Cnt_Mcs_fail = %x\n", + falsealm_cnt->cnt_sb_search_fail); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n", falsealm_cnt->cnt_parity_fail, falsealm_cnt->cnt_rate_illegal, falsealm_cnt->cnt_crc8_fail, - falsealm_cnt->cnt_mcs_fail)); + falsealm_cnt->cnt_mcs_fail); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, " - "Cnt_all = %x\n", + "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n", falsealm_cnt->cnt_ofdm_fail, falsealm_cnt->cnt_cck_fail, - falsealm_cnt->cnt_all)); + falsealm_cnt->cnt_all); } static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) @@ -275,7 +273,7 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { de_digtable.min_undecorated_pwdb_for_dm = 0; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("Not connected to any\n")); + "Not connected to any\n"); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || @@ -283,25 +281,25 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - rtlpriv->dm.UNDEC_SM_PWDB)); + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.UNDEC_SM_PWDB); } else { de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("STA Default Port PWDB = 0x%x\n", - de_digtable.min_undecorated_pwdb_for_dm)); + "STA Default Port PWDB = 0x%x\n", + de_digtable.min_undecorated_pwdb_for_dm); } } else { de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Ext Port or disconnet PWDB = 0x%x\n", - de_digtable.min_undecorated_pwdb_for_dm)); + "AP Ext Port or disconnect PWDB = 0x%x\n", + de_digtable.min_undecorated_pwdb_for_dm); } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n", - de_digtable.min_undecorated_pwdb_for_dm)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", + de_digtable.min_undecorated_pwdb_for_dm); } static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -340,14 +338,14 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) } de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state; } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n", - (de_digtable.cursta_connectctate == DIG_STA_CONNECT ? - "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"))); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n", - (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? - "Low RSSI " : "High RSSI "))); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n", - IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", + de_digtable.cursta_connectctate == DIG_STA_CONNECT ? + "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", + de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? + "Low RSSI " : "High RSSI "); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n", + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)); } @@ -355,12 +353,12 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", de_digtable.cur_igvalue, de_digtable.pre_igvalue, - de_digtable.backoff_val)); + de_digtable.backoff_val); if (de_digtable.dig_enable_flag == false) { - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); de_digtable.pre_igvalue = 0x17; return; } @@ -377,22 +375,21 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) { if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && (rtlpriv->mac80211.vendor == PEER_CISCO)) { - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("IOT_PEER = CISCO\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50 && de_digtable.min_undecorated_pwdb_for_dm < 50) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Early Mode Off\n")); + "Early Mode Off\n"); } else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 && de_digtable.min_undecorated_pwdb_for_dm > 55) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Early Mode On\n")); + "Early Mode On\n"); } } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n"); } } @@ -402,13 +399,13 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) u8 value_igi = de_digtable.cur_igvalue; struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); if (rtlpriv->rtlhal.earlymode_enable) { rtl92d_early_mode_enabled(rtlpriv); de_digtable.last_min_undecorated_pwdb_for_dm = de_digtable.min_undecorated_pwdb_for_dm; } - if (rtlpriv->dm.dm_initialgain_enable == false) + if (!rtlpriv->dm.dm_initialgain_enable) return; /* because we will send data pkt when scanning @@ -421,7 +418,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) /* Not STA mode return tmp */ if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) return; - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) de_digtable.cursta_connectctate = DIG_STA_CONNECT; @@ -438,16 +435,16 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2) value_igi += 2; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", - de_digtable.large_fa_hit, de_digtable.forbidden_igi)); + "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable.large_fa_hit, de_digtable.forbidden_igi); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", - de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); + "dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", + de_digtable.recover_cnt, de_digtable.rx_gain_range_min); /* deal with abnorally large false alarm */ if (falsealm_cnt->cnt_all > 10000) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG(): Abnornally false alarm case.\n")); + "dm_DIG(): Abnormally false alarm case\n"); de_digtable.large_fa_hit++; if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) { @@ -486,11 +483,11 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) } } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", - de_digtable.large_fa_hit, de_digtable.forbidden_igi)); + "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable.large_fa_hit, de_digtable.forbidden_igi); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", - de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); + "dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", + de_digtable.recover_cnt, de_digtable.rx_gain_range_min); if (value_igi > DM_DIG_MAX) value_igi = DM_DIG_MAX; @@ -500,7 +497,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) rtl92d_dm_write_dig(hw); if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) rtl92d_dm_cck_packet_detection_thresh(hw); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n"); } static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw) @@ -528,7 +525,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; return; @@ -538,40 +535,40 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("IBSS Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "IBSS Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (rtlhal->current_bandtype == BAND_ON_5G) { if (undecorated_smoothed_pwdb >= 0x33) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n")); + "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < 0x33) && (undecorated_smoothed_pwdb >= 0x2b)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < 0x2b) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Normal\n")); + "5G:TxHighPwrLevel_Normal\n"); } } else { if (undecorated_smoothed_pwdb >= @@ -579,7 +576,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) @@ -589,19 +586,19 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); } rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; @@ -717,7 +714,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw) u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter - rtlpriv->dm.thermalvalue_rxgain)]) << 12; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("===> Rx Gain %x\n", u4tmp)); + "===> Rx Gain %x\n", u4tmp); for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK, (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp); @@ -741,27 +738,22 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg, if (!memcmp((void *)&temp_cck, (void *)&cckswing_table_ch14[i][2], 4)) { *cck_index_old = (u8) i; - RT_TRACE(rtlpriv, - COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, - temp_cck, *cck_index_old, - rtlpriv->dm.cck_inch14)); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); break; } } else { if (!memcmp((void *) &temp_cck, &cckswing_table_ch1ch13[i][2], 4)) { *cck_index_old = (u8) i; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index = 0x%x, ch14 %d\n", - RCCK0_TXFILTER2, - temp_cck, *cck_index_old, - rtlpriv->dm.cck_inch14)); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); break; } } @@ -884,12 +876,12 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( }; rtlpriv->dm.txpower_trackinginit = true; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n"); thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); rtl92d_phy_ap_calibrate(hw, (thermalvalue - rtlefuse->eeprom_thermalmeter)); if (is2t) @@ -904,10 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( ofdm_index_old[0] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx," - " ofdm_index=0x%x\n", + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", ROFDM0_XATxIQIMBALANCE, - ele_d, ofdm_index_old[0])); + ele_d, ofdm_index_old[0]); break; } } @@ -920,11 +911,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( ofdm_index_old[1] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathB ele_d reg " - "0x%x = 0x%lx, ofdm_index " - "= 0x%x\n", + "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n", ROFDM0_XBTxIQIMBALANCE, ele_d, - ofdm_index_old[1])); + ofdm_index_old[1]); break; } } @@ -952,7 +941,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; rtlpriv->dm.cck_index = cck_index_old; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("reload ofdm index for band switch\n")); + "reload ofdm index for band switch\n"); } rtlpriv->dm.thermalvalue_avg [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue; @@ -995,12 +984,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) : (rtlpriv->dm.thermalvalue_rxgain - thermalvalue); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x" - " eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk); if ((delta_lck > rtlefuse->delta_lck) && (rtlefuse->delta_lck != 0)) { rtlpriv->dm.thermalvalue_lck = thermalvalue; @@ -1036,17 +1023,15 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, OFDM_B_index" - " = 0x%x,cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x,cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x,cck_index = " - "0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x,cck_index = 0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); } for (i = 0; i < rf; i++) { if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) @@ -1070,15 +1055,13 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, OFDM_B_index " - "= 0x%x, cck_index=0x%x\n", + "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n", ofdm_index[0], ofdm_index[1], - cck_index)); + cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x,cck_index = " - "0x%x\n", - ofdm_index[0], cck_index)); + "new OFDM_A_index=0x%x,cck_index = 0x%x\n", + ofdm_index[0], cck_index); } ele_d = (ofdmswing_table[(u8) ofdm_index[0]] & 0xFFC00000) >> 22; @@ -1124,12 +1107,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking for interface %d path A: X =" - " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = " - "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = " - "0x%lx\n", rtlhal->interfaceindex, + "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n", + rtlhal->interfaceindex, val_x, val_y, ele_a, ele_c, ele_d, - val_x, val_y)); + val_x, val_y); if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* Adjust CCK according to IQK result */ @@ -1232,20 +1213,16 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( BIT(28), 0x00); } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking path B: X = 0x%lx, " - "Y = 0x%lx ele_A = 0x%lx ele_C = 0x" - "%lx ele_D = 0x%lx 0xeb4 = 0x%lx " - "0xebc = 0x%lx\n", - val_x, val_y, ele_a, ele_c, - ele_d, val_x, val_y)); + "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n", + val_x, val_y, ele_a, ele_c, + ele_d, val_x, val_y); } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = " - "0x%x RF 0x24 = 0x%x\n", + "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", rtl_get_bbreg(hw, 0xc80, BMASKDWORD), rtl_get_bbreg(hw, 0xc94, BMASKDWORD), rtl_get_rfreg(hw, RF90_PATH_A, 0x24, - BRFREGOFFSETMASK))); + BRFREGOFFSETMASK)); } if ((delta_iqk > rtlefuse->delta_iqk) && (rtlefuse->delta_iqk != 0)) { @@ -1262,7 +1239,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( rtlpriv->dm.thermalvalue = thermalvalue; } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); } static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1273,8 +1250,8 @@ static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) rtlpriv->dm.txpower_trackinginit = false; rtlpriv->dm.txpower_track_control = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking)); + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); } void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) @@ -1289,12 +1266,12 @@ void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16), 0x03); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); + "Trigger 92S Thermal Meter!!\n"); tm_trigger = 1; return; } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); + "Schedule TxPowerTracking direct call!!\n"); rtl92d_dm_txpower_tracking_callback_thermalmeter(hw); tm_trigger = 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h index 69354657f0f..91030ec8ac3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index 82f060bdbc0..f548a8d0068 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -124,14 +124,14 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw, u32 pagenums, remainSize; u32 page, offset; - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) _rtl92d_fill_dummy(bufferPtr, &size); pagenums = size / FW_8192D_PAGE_SIZE; remainSize = size % FW_8192D_PAGE_SIZE; if (pagenums > 8) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 8\n")); + "Page numbers should not greater then 8\n"); } for (page = 0; page < pagenums; page++) { offset = page * FW_8192D_PAGE_SIZE; @@ -158,12 +158,12 @@ static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw) (!(value32 & FWDL_ChkSum_rpt))); if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", + value32); return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); @@ -186,9 +186,9 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) udelay(50); u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); } - RT_ASSERT((delay > 0), ("8051 reset failed!\n")); + RT_ASSERT((delay > 0), "8051 reset failed!\n"); RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("=====> 8051 reset success (%d) .\n", delay)); + "=====> 8051 reset success (%d)\n", delay); } static int _rtl92d_fw_init(struct ieee80211_hw *hw) @@ -197,7 +197,7 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 counter; - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n"); /* polling for FW ready */ counter = 0; do { @@ -205,10 +205,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & MAC0_READY) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready success!! " - "REG_MCUFWDL: 0x%x .\n", + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", rtl_read_byte(rtlpriv, - FW_MAC0_READY))); + FW_MAC0_READY)); return 0; } udelay(5); @@ -216,10 +215,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & MAC1_READY) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready success!! " - "REG_MCUFWDL: 0x%x .\n", + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", rtl_read_byte(rtlpriv, - FW_MAC1_READY))); + FW_MAC1_READY)); return 0; } udelay(5); @@ -228,18 +226,16 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtlhal->interfaceindex == 0) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! MAC0 FW init not ready: " - "0x%x .\n", - rtl_read_byte(rtlpriv, FW_MAC0_READY))); + "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC0_READY)); } else { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! MAC1 FW init not ready: " - "0x%x .\n", - rtl_read_byte(rtlpriv, FW_MAC1_READY))); + "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC1_READY)); } RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n", - rtl_read_dword(rtlpriv, REG_MCUFWDL))); + "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n", + rtl_read_dword(rtlpriv, REG_MCUFWDL)); return -1; } @@ -257,20 +253,20 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) bool fw_downloaded = false, fwdl_in_process = false; unsigned long flags; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; fwsize = rtlhal->fwsize; pfwheader = (u8 *) rtlhal->pfirmware; pfwdata = (u8 *) rtlhal->pfirmware; rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d)," - "FirmwareSubVersion(%d), Signature(%#x)\n", - rtlhal->fw_version, rtlhal->fw_subversion, - GET_FIRMWARE_HDR_SIGNATURE(pfwheader))); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", + rtlhal->fw_version, rtlhal->fw_subversion, + GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Shift 32 bytes for FW header!!\n")); + "Shift 32 bytes for FW header!!\n"); pfwdata = pfwdata + 32; fwsize = fwsize - 32; } @@ -302,8 +298,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) break; else RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Wait for another mac " - "download fw\n")); + "Wait for another mac download fw\n"); } spin_lock_irqsave(&globalmutex_for_fwdownload, flags); value = rtl_read_byte(rtlpriv, 0x1f); @@ -337,11 +332,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("fw is not ready to run!\n")); + "fw is not ready to run!\n"); goto exit; } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("fw is ready to run!\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n"); } exit: err = _rtl92d_fw_init(hw); @@ -381,24 +375,24 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Return as RF is off!!!\n")); + "Return as RF is off!!!\n"); return; } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -418,8 +412,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } boxnum = rtlhal->last_hmeboxnum; @@ -442,7 +435,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); @@ -450,29 +443,29 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, wait_h2c_limmit--; if (wait_h2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); break; } udelay(10); isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); } if (!isfw_read) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); break; } memset(boxcontent, 0, sizeof(boxcontent)); memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: boxcontent[0] &= ~(BIT(7)); @@ -519,7 +512,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } bwrite_sucess = true; @@ -527,26 +520,20 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, if (rtlhal->last_hmeboxnum == 4) rtlhal->last_hmeboxnum = 0; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *cmdbuffer) { - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); - return; - } memset(tmp_cmdbuf, 0, 8); memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); @@ -559,13 +546,13 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[3] = { 0 }; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, ppsc->reg_max_lps_awakeintvl); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode", u1_h2c_set_pwrmode, 3); rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); } @@ -757,28 +744,32 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); totalpacketlen = TOTAL_RESERVED_PKT_LEN; RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", &reserved_page_packet[0], totalpacketlen); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, - totalpacketlen); - rtstatus = _rtl92d_cmd_send_packet(hw, skb); + if (!skb) { + dlok = false; + } else { + memcpy((u8 *) skb_put(skb, totalpacketlen), + &reserved_page_packet, totalpacketlen); + rtstatus = _rtl92d_cmd_send_packet(hw, skb); - if (rtstatus) - dlok = true; + if (rtstatus) + dlok = true; + } if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3); + "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h index 0c4d489eaa4..1ffacdda734 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 9d89d7ccdaf..509f5af38ad 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -166,7 +166,7 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -230,7 +230,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, @@ -261,8 +261,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) min_spacing_to_set); *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); } @@ -275,8 +275,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); break; @@ -310,8 +310,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -344,8 +344,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -361,13 +361,13 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -502,7 +502,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -522,8 +522,8 @@ static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) break; if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); + "Failed to polling write LLT done at address %d!\n", + address); status = false; break; } @@ -707,7 +707,7 @@ static bool _rtl92de_init_mac(struct ieee80211_hw *hw) /* System init */ /* 18. LLT_table_init(Adapter); */ - if (_rtl92de_llt_table_init(hw) == false) + if (!_rtl92de_llt_table_init(hw)) return false; /* Clear interrupt and enable interrupt */ @@ -879,12 +879,12 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) u8 sec_reg_value; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open hw encryption\n")); + "not open hw encryption\n"); return; } sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; @@ -895,7 +895,7 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); } @@ -920,8 +920,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) rtl92d_phy_reset_iqk_result(hw); /* rtlpriv->intf_ops->disable_aspm(hw); */ rtstatus = _rtl92de_init_mac(hw); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); return err; @@ -930,12 +930,8 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW..\n")); - rtlhal->fw_ready = false; + "Failed to download FW. Init HW without FW..\n"); return 1; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; rtlpriv->psc.fw_current_inpsmode = false; @@ -946,7 +942,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) if (rtlhal->earlymode_enable) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EarlyMode Enabled!!!\n")); + "EarlyMode Enabled!!!\n"); tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0); tmp_u1b = tmp_u1b | 0x1f; @@ -1064,10 +1060,10 @@ static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw) value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (!(value32 & 0x000f0000)) { version = VERSION_TEST_CHIP_92D_SINGLEPHY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n"); } else { version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n"); } return version; } @@ -1092,8 +1088,8 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw, _rtl92de_disable_bcn_sub_func(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: No such media " - "status(%x).\n", type)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); } bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL); switch (type) { @@ -1102,30 +1098,30 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw, ledaction = LED_CTL_LINK; bcnfunc_enable &= 0xF7; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; bcnfunc_enable |= 0x08; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; bcnfunc_enable &= 0xF7; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; bcnfunc_enable |= 0x08; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1151,7 +1147,7 @@ void rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); - } else if (check_bssid == false) { + } else if (!check_bssid) { reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); @@ -1189,7 +1185,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw) indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) { RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, - ("Do IQK for channel:%d.\n", channel)); + "Do IQK for channel:%d\n", channel); rtl92d_phy_iq_calibrate(hw); } } @@ -1214,7 +1210,7 @@ void rtl92de_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } @@ -1305,8 +1301,8 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL, - rtl_read_byte(rtlpriv, REG_SPS0_CTRL))); + "In PowerOff,reg0x%x=%X\n", + REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL)); /* r. Note: for PCIe interface, PON will not turn */ /* off m-bias and BandGap in PCIe suspend mode. */ @@ -1319,7 +1315,7 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_power, flags); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n"); } void rtl92de_card_disable(struct ieee80211_hw *hw) @@ -1377,7 +1373,7 @@ void rtl92de_card_disable(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); udelay(50); rtl_write_byte(rtlpriv, REG_CR, 0x0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n"); if (rtl92d_phy_check_poweroff(hw)) _rtl92de_poweroff_adapter(hw); return; @@ -1425,7 +1421,7 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw) u16 bcn_interval = mac->beacon_interval; RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + "beacon_interval:%d\n", bcn_interval); /* rtl92de_disable_interrupt(hw); */ rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); /* rtl92de_enable_interrupt(hw); */ @@ -1437,8 +1433,8 @@ void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; if (rm_msr) @@ -1615,9 +1611,9 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, rtlefuse->internal_pa_5g[1] = !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Is D cut,Internal PA0 %d Internal PA1 %d\n", + "Is D cut,Internal PA0 %d Internal PA1 %d\n", rtlefuse->internal_pa_5g[0], - rtlefuse->internal_pa_5g[1])) + rtlefuse->internal_pa_5g[1]); } rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; @@ -1667,14 +1663,14 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, if (rtlefuse->eeprom_c9 == 0xFF) rtlefuse->eeprom_c9 = 0x00; RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("CrystalCap = 0x%x\n", rtlefuse->crystalcap)); + "CrystalCap = 0x%x\n", rtlefuse->crystalcap); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk, - rtlefuse->delta_lck)); + "Delta_IQK = 0x%x Delta_LCK = 0x%x\n", + rtlefuse->delta_iqk, rtlefuse->delta_lck); for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) { for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { @@ -1710,11 +1706,11 @@ static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw, if (macphy_crvalue & BIT(3)) { rtlhal->macphymode = SINGLEMAC_SINGLEPHY; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode SINGLEMAC_SINGLEPHY\n")); + "MacPhyMode SINGLEMAC_SINGLEPHY\n"); } else { rtlhal->macphymode = DUALMAC_DUALPHY; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode DUALMAC_DUALPHY\n")); + "MacPhyMode DUALMAC_DUALPHY\n"); } } @@ -1741,15 +1737,15 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw) switch (chipvalue) { case 0xAA55: chipver |= CHIP_92D_C_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n"); break; case 0x9966: chipver |= CHIP_92D_D_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); break; default: chipver |= CHIP_92D_D_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unkown CUT!\n"); break; } rtlpriv->rtlhal.version = chipver; @@ -1775,23 +1771,23 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } if (rtlefuse->autoload_failflag) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); return; } rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; @@ -1802,16 +1798,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROMId = 0x%4x\n", eeprom_id)); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); /* Read Permanent MAC address */ if (rtlhal->interfaceindex == 0) { @@ -1827,8 +1822,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) } rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, rtlefuse->dev_addr); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo); /* Read Channel Plan */ @@ -1849,7 +1843,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; rtlefuse->txpwr_fromeprom = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); } void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) @@ -1863,19 +1857,19 @@ void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); rtlefuse->autoload_status = tmp_u1b; if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92de_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } return; } @@ -1958,8 +1952,8 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw, (shortgi_rate << 4) | (shortgi_rate); } rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2092,8 +2086,8 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x value0:%x value1:%x\n", - ratr_bitmap, value[0], value[1])); + "ratr_bitmap :%x value0:%x value1:%x\n", + ratr_bitmap, value[0], value[1]); rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value); if (macid != 0) sta_entry->ratr_index = ratr_index; @@ -2153,14 +2147,13 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); + "GPIOChangeRF - HW Radio ON, RF ON\n"); e_rfpowerstate_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; - } else if ((ppsc->hwradiooff == false) - && (e_rfpowerstate_toset == ERFOFF)) { + } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); e_rfpowerstate_toset = ERFOFF; ppsc->hwradiooff = true; actuallyset = true; @@ -2204,7 +2197,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, u8 idx; u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); @@ -2230,8 +2223,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2248,9 +2241,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, ("Can not " - "find free hw security" - " cam entry\n")); + DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2262,29 +2254,29 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv-> sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, CAM_CONFIG_NO_USEDK, @@ -2292,7 +2284,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, sec.key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h index ad44ffa520e..7c9f7a2f1e4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index f1552f4df65..76a57ae4af3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -45,8 +45,8 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -71,7 +71,7 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -83,8 +83,8 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -106,7 +106,7 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -153,7 +153,7 @@ void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); _rtl92ce_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h index 57f4a3c583d..a29df30c302 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 0883349e1c8..34591eeb837 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -204,8 +204,8 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) u32 returnvalue, originalvalue, bitshift; u8 dbi_direct; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) { /* mac1 use phy0 read radio_b. */ /* mac0 use phy1 read radio_b. */ @@ -220,8 +220,9 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) } bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; } @@ -233,8 +234,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, u8 dbi_direct = 0; u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (rtlhal->during_mac1init_radioa) dbi_direct = BIT(3); else if (rtlhal->during_mac0init_radiob) @@ -255,8 +257,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct); else rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, @@ -300,8 +303,8 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } @@ -319,8 +322,8 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw, /* T65 RF */ data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, @@ -330,17 +333,17 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; unsigned long flags; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -353,8 +356,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, unsigned long flags; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); if (bitmask == 0) return; spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); @@ -369,9 +372,9 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data); } spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) @@ -381,10 +384,10 @@ bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = MAC_2T_ARRAYLENGTH; ptrarray = rtl8192de_mac_2tarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { @@ -561,25 +564,25 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_arraylen = AGCTAB_ARRAYLENGTH; agctab_array_table = rtl8192de_agctab_array; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n")); + " ===> phy:MAC0, Rtl819XAGCTAB_Array\n"); } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { agctab_arraylen = AGCTAB_2G_ARRAYLENGTH; agctab_array_table = rtl8192de_agctab_2garray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n")); + " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"); } else { agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH; agctab_5garray_table = rtl8192de_agctab_5garray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n")); + " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"); } } phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH; phy_regarray_table = rtl8192de_phy_reg_2tarray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:Rtl819XPHY_REG_Array_PG\n")); + " ===> phy:Rtl819XPHY_REG_Array_PG\n"); if (configtype == BASEBAND_CONFIG_PHY_REG) { for (i = 0; i < phy_reg_arraylen; i = i + 2) { if (phy_regarray_table[i] == 0xfe) @@ -598,10 +601,9 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { if (rtlhal->interfaceindex == 0) { @@ -613,15 +615,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_Array_" - "Table[0] is %ul " - "Rtl819XPHY_REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_array_table[i], - agctab_array_table[i + 1])); + agctab_array_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Normal Chip, MAC0, load " - "Rtl819XAGCTAB_Array\n")); + "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n"); } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -632,14 +631,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_Array_" - "Table[0] is %ul Rtl819XPHY_" - "REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_array_table[i], - agctab_array_table[i + 1])); + agctab_array_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Load Rtl819XAGCTAB_2GArray\n")); + "Load Rtl819XAGCTAB_2GArray\n"); } else { for (i = 0; i < agctab_5garraylen; i = i + 2) { rtl_set_bbreg(hw, @@ -650,14 +647,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_5GArray_" - "Table[0] is %ul Rtl819XPHY_" - "REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_5GArray_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_5garray_table[i], - agctab_5garray_table[i + 1])); + agctab_5garray_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Load Rtl819XAGCTAB_5GArray\n")); + "Load Rtl819XAGCTAB_5GArray\n"); } } } @@ -670,152 +665,51 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); + int index; + + if (regaddr == RTXAGC_A_RATE18_06) + index = 0; + else if (regaddr == RTXAGC_A_RATE54_24) + index = 1; + else if (regaddr == RTXAGC_A_CCK1_MCS32) + index = 6; + else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) + index = 7; + else if (regaddr == RTXAGC_A_MCS03_MCS00) + index = 2; + else if (regaddr == RTXAGC_A_MCS07_MCS04) + index = 3; + else if (regaddr == RTXAGC_A_MCS11_MCS08) + index = 4; + else if (regaddr == RTXAGC_A_MCS15_MCS12) + index = 5; + else if (regaddr == RTXAGC_B_RATE18_06) + index = 8; + else if (regaddr == RTXAGC_B_RATE54_24) + index = 9; + else if (regaddr == RTXAGC_B_CCK1_55_MCS32) + index = 14; + else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) + index = 15; + else if (regaddr == RTXAGC_B_MCS03_MCS00) + index = 10; + else if (regaddr == RTXAGC_B_MCS07_MCS04) + index = 11; + else if (regaddr == RTXAGC_B_MCS11_MCS08) + index = 12; + else if (regaddr == RTXAGC_B_MCS15_MCS12) + index = 13; + else + return; - if (regaddr == RTXAGC_A_RATE18_06) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][0])); - } - if (regaddr == RTXAGC_A_RATE54_24) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][1])); - } - if (regaddr == RTXAGC_A_CCK1_MCS32) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][6])); - } - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][7])); - } - if (regaddr == RTXAGC_A_MCS03_MCS00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][2])); - } - if (regaddr == RTXAGC_A_MCS07_MCS04) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][3])); - } - if (regaddr == RTXAGC_A_MCS11_MCS08) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][4])); - } - if (regaddr == RTXAGC_A_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][5])); - } - if (regaddr == RTXAGC_B_RATE18_06) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][8])); - } - if (regaddr == RTXAGC_B_RATE54_24) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][9])); - } - if (regaddr == RTXAGC_B_CCK1_55_MCS32) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][14])); - } - if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][15])); - } - if (regaddr == RTXAGC_B_MCS03_MCS00) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][10])); - } - if (regaddr == RTXAGC_B_MCS07_MCS04) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][11])); - } - if (regaddr == RTXAGC_B_MCS11_MCS08) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][12])); - } - if (regaddr == RTXAGC_B_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = - data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][13])); + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, index, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][index]); + if (index == 13) rtlphy->pwrgroup_cnt++; - } } static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, @@ -849,7 +743,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -861,17 +755,17 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } /* if (rtlphy->rf_type == RF_1T2R) { * _rtl92c_phy_bb_config_1t(hw); - * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); *} */ if (rtlefuse->autoload_failflag == false) { @@ -879,14 +773,14 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw, BASEBAND_CONFIG_PHY_REG); } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, @@ -951,19 +845,17 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_array_table = rtl8192de_radiob_2t_int_paarray; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PHY_ConfigRFWithHeaderFile() " - "Radio_A:Rtl819XRadioA_1TArray\n")); + "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PHY_ConfigRFWithHeaderFile() " - "Radio_B:Rtl819XRadioB_1TArray\n")); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n"); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); /* this only happens when DMDP, mac0 start on 2.4G, * mac1 start on 5G, mac 0 has to set phy0&phy1 * pathA or mac1 has to set phy0&phy1 pathA */ if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> althougth Path A, we load radiob.txt\n")); + " ===> althougth Path A, we load radiob.txt\n"); radioa_arraylen = radiob_arraylen; radioa_array_table = radiob_array_table; } @@ -1022,11 +914,11 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -1046,19 +938,18 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) rtlphy->default_initialgain[3] = (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, BMASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, BMASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel, @@ -1137,7 +1028,7 @@ void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 cckpowerlevel[2], ofdmpowerlevel[2]; - if (rtlefuse->txpwr_fromeprom == false) + if (!rtlefuse->txpwr_fromeprom) return; channel = _rtl92c_phy_get_rightchnlplace(channel); _rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0], @@ -1172,7 +1063,7 @@ void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -1193,14 +1084,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, return; if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); + "FALSE driver sleep or unload\n"); return; } rtlphy->set_bwmode_inprogress = true; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); switch (rtlphy->current_chan_bw) { @@ -1218,7 +1108,7 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } switch (rtlphy->current_chan_bw) { @@ -1250,13 +1140,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw) @@ -1273,7 +1163,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 value8; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); rtlhal->bandset = band; rtlhal->current_bandtype = band; if (IS_92D_SINGLEPHY(rtlhal->version)) @@ -1283,13 +1173,13 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) /* reconfig BB/RF according to wireless mode */ if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* BB & RF Config */ - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n"); if (rtlhal->interfaceindex == 1) _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); } else { /* 5G band */ - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n"); if (rtlhal->interfaceindex == 1) _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); @@ -1317,7 +1207,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) 0 ? REG_MAC0 : REG_MAC1), value8); } mdelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n"); } static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, @@ -1329,9 +1219,9 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, u8 group, i; unsigned long flag = 0; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); /* fc area 0xd2c */ @@ -1353,14 +1243,13 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, } else { /* G band. */ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Load RF IMR parameters for G band. IMR already " - "setting %d\n", - rtlpriv->rtlhal.load_imrandiqk_setting_for2g)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + "Load RF IMR parameters for G band. IMR already setting %d\n", + rtlpriv->rtlhal.load_imrandiqk_setting_for2g); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) { RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Load RF IMR parameters " - "for G band. %d\n", rfpath)); + "Load RF IMR parameters for G band. %d\n", + rfpath); rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, @@ -1378,7 +1267,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, @@ -1388,7 +1277,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); /*----Store original RFENV control type----*/ switch (rfpath) { case RF90_PATH_A: @@ -1414,7 +1303,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, /*Set 0 to 12 bits for 8255 */ rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); udelay(1); - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, @@ -1424,7 +1313,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n"); /*----Restore RFENV control type----*/ ; switch (rfpath) { case RF90_PATH_A: @@ -1437,7 +1326,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, *pu4_regval); break; } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n"); } static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) @@ -1451,13 +1340,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) bool need_pwr_down = false, internal_pa = false; u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n"); /* config path A for 5G */ if (rtlhal->current_bandtype == BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); u4tmp = curveindex_5g[channel - 1]; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, " - "0x28 = 0x%x !!\n", u4tmp)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); for (i = 0; i < RF_CHNL_NUM_5G; i++) { if (channel == rf_chnl_5g[i] && channel <= 140) index = 0; @@ -1503,12 +1392,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) rf_reg_pram_c_5g[index][i]); } RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("offset 0x%x value 0x%x " - "path %d index %d readback 0x%x\n", - rf_reg_for_c_cut_5g[i], - rf_reg_pram_c_5g[index][i], path, - index, rtl_get_rfreg(hw, (enum radio_path)path, - rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK))); + "offset 0x%x value 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_5g[i], + rf_reg_pram_c_5g[index][i], + path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + BRFREGOFFSETMASK)); } if (need_pwr_down) _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); @@ -1541,11 +1431,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) BRFREGOFFSETMASK, rf_pram_c_5g_int_pa[index][i]); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("offset 0x%x value 0x%x " - "path %d index %d\n", + "offset 0x%x value 0x%x path %d index %d\n", rf_for_c_cut_5g_internal_pa[i], rf_pram_c_5g_int_pa[index][i], - rfpath, index)); + rfpath, index); } } else { rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, @@ -1553,10 +1442,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) } } } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); u4tmp = curveindex_2g[channel - 1]; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, " - "0x28 = 0x%x !!\n", u4tmp)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); if (channel == 1 || channel == 2 || channel == 4 || channel == 9 || channel == 10 || channel == 11 || channel == 12) index = 0; @@ -1590,18 +1479,17 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) rf_reg_param_for_c_cut_2g [index][i]); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("offset 0x%x value 0x%x mak 0x%x path %d " - "index %d readback 0x%x\n", - rf_reg_for_c_cut_2g[i], - rf_reg_param_for_c_cut_2g[index][i], - rf_reg_mask_for_c_cut_2g[i], path, index, - rtl_get_rfreg(hw, (enum radio_path)path, - rf_reg_for_c_cut_2g[i], - BRFREGOFFSETMASK))); + "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_2g[i], + rf_reg_param_for_c_cut_2g[index][i], + rf_reg_mask_for_c_cut_2g[i], path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + BRFREGOFFSETMASK)); } RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", - rf_syn_g4_for_c_cut_2g | (u4tmp << 11))); + "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, BRFREGOFFSETMASK, @@ -1611,7 +1499,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) if (rtlhal->during_mac0init_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) @@ -1648,9 +1536,9 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) u32 regeac, rege94, rege9c, regea4; u8 result = 0; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); if (rtlhal->interfaceindex == 0) { rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f); @@ -1668,26 +1556,26 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206); } /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* One shot, path A LOK & IQK */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path A LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path A LOK & IQK\n", + IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) && (((rege9c & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; @@ -1698,7 +1586,7 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) (((regeac & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n"); return result; } @@ -1719,9 +1607,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, TxOKBit = BIT(31); RxOKBit = BIT(30); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307); @@ -1734,7 +1622,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000); } /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* path-A PA on */ rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60); @@ -1742,29 +1630,29 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, for (i = 0; i < retrycount; i++) { /* One shot, path A LOK & IQK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("One shot, path A LOK & IQK!\n")); + "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path A LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); if (!(regeac & TxOKBit) && (((rege94 & 0x03FF0000) >> 16) != 0x142)) { result |= 0x01; } else { /* if Tx not OK, ignore Rx */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A Tx IQK fail!!\n")); + "Path A Tx IQK fail!!\n"); continue; } @@ -1775,7 +1663,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, break; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A Rx IQK fail!!\n")); + "Path A Rx IQK fail!!\n"); } } /* path A PA off */ @@ -1793,27 +1681,26 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) u32 regeac, regeb4, regebc, regec4, regecc; u8 result = 0; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); /* One shot, path B LOK & IQK */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002); rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path B LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) && (((regebc & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; @@ -1823,7 +1710,7 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) (((regecc & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n"); return result; } @@ -1837,9 +1724,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) u8 i; u8 retrycount = 2; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000); @@ -1852,7 +1739,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960); /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* path-B PA on */ @@ -1862,26 +1749,26 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) for (i = 0; i < retrycount; i++) { /* One shot, path B LOK & IQK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("One shot, path A LOK & IQK!\n")); + "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path B LOK & IQK.\n", 10)); + "Delay %d ms for One shot, path B LOK & IQK.\n", 10); mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142)) result |= 0x01; @@ -1893,7 +1780,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) break; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Rx IQK fail!!\n")); + "Path B Rx IQK fail!!\n"); } } @@ -1912,7 +1799,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n"); for (i = 0; i < regnum; i++) adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD); } @@ -1923,7 +1810,7 @@ static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n"); for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); @@ -1937,7 +1824,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw, u32 i; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Reload ADDA power saving parameters !\n")); + "Reload ADDA power saving parameters !\n"); for (i = 0; i < regnum; i++) rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]); } @@ -1948,7 +1835,7 @@ static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n"); for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); rtl_write_byte(rtlpriv, macreg[i], macbackup[i]); @@ -1961,7 +1848,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw, u32 pathon; u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n"); pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4; if (patha_on) pathon = rtlpriv->rtlhal.interfaceindex == 0 ? @@ -1976,7 +1863,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n"); rtl_write_byte(rtlpriv, macreg[0], 0x3F); for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) @@ -1988,7 +1875,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0); rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000); @@ -2001,7 +1888,7 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) u32 mode; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI"))); + "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI"); mode = pi_mode ? 0x01000100 : 0x01000000; rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode); rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode); @@ -2033,12 +1920,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], const u32 retrycount = 2; u32 bbvalue; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n"); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", - (is2t ? "2T2R" : "1T1R"))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); /* Save ADDA parameters, turn Path A ADDA on */ _rtl92d_phy_save_adda_registers(hw, adda_reg, @@ -2076,7 +1963,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], if (is2t) rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); /* IQ calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00); rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); @@ -2084,7 +1971,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], patha_ok = _rtl92d_phy_patha_iqk(hw, is2t); if (patha_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Success!!\n")); + "Path A IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & @@ -2097,7 +1984,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } else if (i == (retrycount - 1) && patha_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Only Tx Success!!\n")); + "Path A IQK Only Tx Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; @@ -2106,7 +1993,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } } if (0x00 == patha_ok) - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n"); if (is2t) { _rtl92d_phy_patha_standby(hw); /* Turn Path B ADDA on */ @@ -2115,7 +2002,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], pathb_ok = _rtl92d_phy_pathb_iqk(hw); if (pathb_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK Success!!\n")); + "Path B IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, @@ -2128,7 +2015,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } else if (i == (retrycount - 1) && pathb_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Only Tx IQK Success!!\n")); + "Path B Only Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, @@ -2137,12 +2024,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } if (0x00 == pathb_ok) RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK failed!!\n")); + "Path B IQK failed!!\n"); } /* Back to BB mode, load original value */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); if (t != 0) { @@ -2167,7 +2054,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); } static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, @@ -2199,13 +2086,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, /* Note: IQ calibration must be performed after loading * PHY_REG.txt , and radio_a, radio_b.txt */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n"); mdelay(IQK_DELAY_TIME * 20); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", - (is2t ? "2T2R" : "1T1R"))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); /* Save ADDA parameters, turn Path A ADDA on */ _rtl92d_phy_save_adda_registers(hw, adda_reg, rtlphy->adda_backup, @@ -2242,13 +2129,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); /* IQ calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00); rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t); if (patha_ok == 0x03) { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & @@ -2259,14 +2146,14 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, 0x3FF0000) >> 16; } else if (patha_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Only Tx Success!!\n")); + "Path A IQK Only Tx Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 0x3FF0000) >> 16; } else { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n"); } if (is2t) { /* _rtl92d_phy_patha_standby(hw); */ @@ -2275,7 +2162,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw); if (pathb_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK Success!!\n")); + "Path B IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & @@ -2286,20 +2173,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, 0x3FF0000) >> 16; } else if (pathb_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Only Tx IQK Success!!\n")); + "Path B Only Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & 0x3FF0000) >> 16; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK failed!!\n")); + "Path B IQK failed!!\n"); } } /* Back to BB mode, load original value */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); if (t != 0) { if (is2t) @@ -2321,7 +2208,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, rtlphy->adda_backup, IQK_ADDA_REG_NUM); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); } static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw, @@ -2395,8 +2282,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, rtlhal->macphymode == DUALMAC_DUALPHY; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQ Calibration %s !\n", - (iqk_ok) ? "Success" : "Failed")); + "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); if (final_candidate == 0xFF) { return; } else if (iqk_ok) { @@ -2406,8 +2292,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, if ((val_x & 0x00000200) != 0) val_x = val_x | 0xFFFFFC00; tx0_a = (val_x * oldval_0) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x," - " oldval_0 0x%x\n", val_x, tx0_a, oldval_0)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n", + val_x, tx0_a, oldval_0); rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a); rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), ((val_x * oldval_0 >> 7) & 0x1)); @@ -2419,8 +2306,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, rtlhal->current_bandtype == BAND_ON_5G) val_y += 3; tx0_c = (val_y * oldval_0) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n", - val_y, tx0_c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Y = 0x%lx, tx0_c = 0x%lx\n", + val_y, tx0_c); rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, ((tx0_c & 0x3C0) >> 6)); rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000, @@ -2428,11 +2316,11 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), ((val_y * oldval_0 >> 7) & 0x1)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n", - rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, - BMASKDWORD))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n", + rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD)); if (txonly) { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); return; } reg = result[final_candidate][2]; @@ -2452,8 +2340,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, u32 oldval_1, val_x, tx1_a, reg; long val_y, tx1_c; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n", - (iqk_ok) ? "Success" : "Failed")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n", + iqk_ok ? "Success" : "Failed"); if (final_candidate == 0xFF) { return; } else if (iqk_ok) { @@ -2463,8 +2351,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, if ((val_x & 0x00000200) != 0) val_x = val_x | 0xFFFFFC00; tx1_a = (val_x * oldval_1) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n", - val_x, tx1_a)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n", + val_x, tx1_a); rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a); rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), ((val_x * oldval_1 >> 7) & 0x1)); @@ -2474,8 +2362,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, if (rtlhal->current_bandtype == BAND_ON_5G) val_y += 3; tx1_c = (val_y * oldval_1) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n", - val_y, tx1_c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n", + val_y, tx1_c); rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, ((tx1_c & 0x3C0) >> 6)); rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000, @@ -2507,7 +2395,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) unsigned long flag = 0; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Start!!!channel %d\n", rtlphy->current_channel)); + "IQK:Start!!!channel %d\n", rtlphy->current_channel); for (i = 0; i < 8; i++) { result[0][i] = 0; result[1][i] = 0; @@ -2521,7 +2409,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) is23simular = false; is13simular = false; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK !!!currentband %d\n", rtlhal->current_bandtype)); + "IQK !!!currentband %d\n", rtlhal->current_bandtype); rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); for (i = 0; i < 3; i++) { if (rtlhal->current_bandtype == BAND_ON_5G) { @@ -2573,10 +2461,9 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) regec4 = result[i][6]; regecc = result[i][7]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " - "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, - regecc)); + regecc); } if (final_candidate != 0xff) { rtlphy->reg_e94 = rege94 = result[final_candidate][0]; @@ -2588,12 +2475,11 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) regec4 = result[final_candidate][6]; regecc = result[final_candidate][7]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: final_candidate is %x\n", final_candidate)); + "IQK: final_candidate is %x\n", final_candidate); RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " - "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, - regecc)); + regecc); patha_ok = pathb_ok = true; } else { rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */ @@ -2618,7 +2504,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) true; RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, - ("\nIQK OK indexforchannel %d.\n", indexforchannel)); + "IQK OK indexforchannel %d\n", indexforchannel); } } @@ -2629,17 +2515,17 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); u8 indexforchannel; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel); /*------Do IQK for normal chip and test chip 5G band------- */ indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("indexforchannel %d done %d\n", indexforchannel, - rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n", + indexforchannel, + rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done); if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done && rtlphy->need_iqk) { /* Re Do IQK. */ RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, - ("Do IQK Matrix reg for channel:%d....\n", channel)); + "Do IQK Matrix reg for channel:%d....\n", channel); rtl92d_phy_iq_calibrate(hw); } else { /* Just load the value. */ @@ -2647,8 +2533,8 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) if (((!rtlhal->load_imrandiqk_setting_for2g) && indexforchannel == 0) || indexforchannel > 0) { RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Just Read IQK Matrix reg for channel:%d" - "....\n", channel)); + "Just Read IQK Matrix reg for channel:%d....\n", + channel); if ((rtlphy->iqk_matrix_regsetting[indexforchannel]. value[0] != NULL) /*&&(regea4 != 0) */) @@ -2672,7 +2558,7 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) } } rtlphy->need_iqk = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2) @@ -2727,8 +2613,8 @@ static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw, } } smallest_abs_val = 0xffffffff; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i, - curveindex[i])); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n", + i, curveindex[i]); } } @@ -2743,14 +2629,14 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, u32 u4tmp = 0, u4regvalue = 0; bool bneed_powerdown_radio = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n", - rtlpriv->rtlhal.current_bandtype)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n", + rtlpriv->rtlhal.current_bandtype); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ u4tmp = curveindex_5g[channel-1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp)); + "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp); if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && rtlpriv->rtlhal.interfaceindex == 1) { bneed_powerdown_radio = @@ -2769,7 +2655,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { u4tmp = curveindex_2g[channel-1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp)); + "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp); if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && rtlpriv->rtlhal.interfaceindex == 0) { bneed_powerdown_radio = @@ -2781,14 +2667,14 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, } rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", - rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800))); + "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", + rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); if (bneed_powerdown_radio) _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); if (rtlpriv->rtlhal.during_mac0init_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) @@ -2836,20 +2722,20 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) RF_SYN_G6, BRFREGOFFSETMASK); } RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_LCK finish delay for %d ms=2\n", timecount)); + "PHY_LCK finish delay for %d ms=2\n", timecount); u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK); if (index == 0 && rtlhal->interfaceindex == 0) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("path-A / 5G LCK\n")); + "path-A / 5G LCK\n"); } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("path-B / 2.4G LCK\n")); + "path-B / 2.4G LCK\n"); } memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2); /* Set LC calibration off */ rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, 0x08000, 0x0); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n"); /* save Curve-counting number */ for (i = 0; i < CV_CURVE_CNT; i++) { u32 readval = 0, readval2 = 0; @@ -2899,7 +2785,7 @@ static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "cosa PHY_LCK ver=2\n"); _rtl92d_phy_lc_calibrate_sw(hw, is2t); } @@ -2917,8 +2803,8 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) rtlphy->lck_inprogress = true; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("LCK:Start!!! currentband %x delay %d ms\n", - rtlhal->current_bandtype, timecount)); + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); if (IS_92D_SINGLEPHY(rtlhal->version)) { _rtl92d_phy_lc_calibrate(hw, true); } else { @@ -2926,7 +2812,7 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) _rtl92d_phy_lc_calibrate(hw, false); } rtlphy->lck_inprogress = false; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n"); } void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) @@ -2941,7 +2827,7 @@ static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } if (cmdtableidx >= cmdtablesz) @@ -2962,10 +2848,10 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw) u8 i; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("settings regs %d default regs %d\n", - (int)(sizeof(rtlphy->iqk_matrix_regsetting) / - sizeof(struct iqk_matrix_regs)), - IQK_MATRIX_REG_NUM)); + "settings regs %d default regs %d\n", + (int)(sizeof(rtlphy->iqk_matrix_regsetting) / + sizeof(struct iqk_matrix_regs)), + IQK_MATRIX_REG_NUM); /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100; @@ -3084,7 +2970,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } break; @@ -3111,7 +2997,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); return 0; } while (rtlphy->lck_inprogress && timecount < timeout) { @@ -3133,19 +3019,18 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) * 5G and 2.4G band. */ if (channel <= 14) return 0; - RT_ASSERT((channel > 14), ("5G but channel<=14")); + RT_ASSERT((channel > 14), "5G but channel<=14\n"); break; case BAND_ON_2_4G: /* Get first channel error when change between * 5G and 2.4G band. */ if (channel > 14) return 0; - RT_ASSERT((channel <= 14), ("2G but channel>14")); + RT_ASSERT((channel <= 14), "2G but channel>14\n"); break; default: - RT_ASSERT(false, - ("Invalid WirelessMode(%#x)!!\n", - rtlpriv->mac80211.mode)); + RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n", + rtlpriv->mac80211.mode); break; } rtlphy->sw_chnl_inprogress = true; @@ -3154,7 +3039,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) rtlphy->sw_chnl_stage = 0; rtlphy->sw_chnl_step = 0; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + "switch to channel%d\n", rtlphy->current_channel); do { if (!rtlphy->sw_chnl_inprogress) @@ -3171,7 +3056,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); rtlphy->sw_chnl_inprogress = false; return 1; } @@ -3182,8 +3067,8 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; @@ -3197,12 +3082,12 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); } bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) @@ -3212,23 +3097,23 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) bool postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); postprocessing = true; break; case IO_CMD_PAUSE_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); postprocessing = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -3239,7 +3124,7 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92d_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); return true; } @@ -3297,7 +3182,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Fail !!! Switch RF timeout.\n")); + "Fail !!! Switch RF timeout\n"); return; } /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */ @@ -3332,20 +3217,18 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) && - (InitializeCount < 10)); + } while (!rtstatus && (InitializeCount < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("awake, sleeped:%d ms state_" - "inap:%x\n", + "awake, sleeped:%d ms state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies), - rtlpriv->psc.state_inap)); + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; _rtl92d_phy_set_rfon(hw); } @@ -3360,7 +3243,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF: if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -3385,41 +3268,40 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else if (rtlpci->pdev->current_state != PCI_D0) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("eRf Off/Sleep: %d times TcbBusyQueu" - "e[%d] !=0 but lower power state!\n", - (i + 1), queue_id)); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", + i + 1, queue_id); break; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times TcbBusyQueu" - "e[%d] =%d " - "before doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times TcbBusyQueue[%d] " - "= %d !\n", - MAX_DOZE_WAITING_TIMES_9x, queue_id, - skb_queue_len(&ring->queue))); + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("Set rfsleep awaked:%d ms\n", - jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies))); - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms " - "state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), rtlpriv->psc.state_inap)); + "Set rfsleep awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92d_phy_set_rfsleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } @@ -3437,17 +3319,17 @@ void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw) switch (rtlhal->macphymode) { case DUALMAC_DUALPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: DUALMAC_DUALPHY\n")); + "MacPhyMode: DUALMAC_DUALPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF3); break; case SINGLEMAC_SINGLEPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: SINGLEMAC_SINGLEPHY\n")); + "MacPhyMode: SINGLEMAC_SINGLEPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF4); break; case DUALMAC_SINGLEPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: DUALMAC_SINGLEPHY\n")); + "MacPhyMode: DUALMAC_SINGLEPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF1); break; } @@ -3578,7 +3460,7 @@ void rtl92d_phy_set_poweron(struct ieee80211_hw *hw) } } if (i == 200) - RT_ASSERT(false, ("Another mac power off over time\n")); + RT_ASSERT(false, "Another mac power off over time\n"); } } @@ -3615,7 +3497,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); u8 rfpath, i; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */ if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* r_select_5G for path_A/B,0x878 */ @@ -3764,7 +3646,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) } else { rtl92d_phy_enable_anotherphy(hw, false); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MAC1 use DBI to update 0x888")); + "MAC1 use DBI to update 0x888\n"); /* 0x888 */ rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN, rtl92de_read_dword_dbi(hw, @@ -3789,9 +3671,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) BRFREGOFFSETMASK); } for (i = 0; i < 2; i++) - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[i])); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[i]); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n"); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h index a52c824b41e..f074952bf25 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h index 131acc306fc..ebb1d5f5e7b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -998,7 +998,6 @@ #define SCR_RXBCUSEDK BIT(7) /* General definitions */ -#define MAC_ADDR_LEN 6 #define LAST_ENTRY_OF_TX_PKT_BUFFER 255 #define LAST_ENTRY_OF_TX_PKT_BUFFER_DUAL_MAC 127 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index db27cebaac2..3066a7fb0b5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -50,8 +50,8 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) BIT(11), 0x01); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("20M RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[rfpath])); + "20M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); } break; @@ -62,13 +62,13 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11), 0x00); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("40M RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[rfpath])); + "40M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); } break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -127,23 +127,23 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, tmpval = tx_agc[RF90_PATH_A] & 0xff; rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, @@ -165,8 +165,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, (powerbase0 << 8) | powerbase0; *(ofdmbase + i) = powerbase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { @@ -179,8 +179,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, (powerbase1 << 8) | powerbase1; *(mcsbase + i) = powerbase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -232,9 +232,9 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " - "performance, writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; case 1: if (rtlphy->pwrgroup_cnt == 1) @@ -253,33 +253,31 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, " - "20MHz, writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - writeval)); + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); } break; case 2: writeval = ((index < 2) ? powerbase0[rf] : powerbase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, " - "writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht40[rf] - [channel - 1])); + [channel - 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht20[rf] - [channel - 1])); + [channel - 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -308,13 +306,13 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeval = customer_limit + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeval rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + "Customer, writeval rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; default: chnlgroup = 0; @@ -323,9 +321,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeval " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + "RTK better performance, writeval rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; } *(p_outwriteval + rf) = writeval; @@ -367,7 +364,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw, regoffset = regoffset_b[index]; rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeval)); + "Set 0x%x = %08x\n", regoffset, writeval); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12)) || @@ -423,11 +420,11 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n"); /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ u1btmp = rtl_read_byte(rtlpriv, mac_reg); if (!(u1btmp & mac_on_bit)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n"); /* Enable BB and RF power */ rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL, rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) | @@ -437,7 +434,7 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) * and radio_b.txt has been load. */ bresult = false; } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n"); return bresult; } @@ -453,17 +450,17 @@ void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); /* check MAC0 enable or not again now, if * enabled, not power down radio A. */ u1btmp = rtl_read_byte(rtlpriv, mac_reg); if (!(u1btmp & mac_on_bit)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n"); /* power down RF radio A according to YuNan's advice. */ rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER, 0x00000000, direct); } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); } bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) @@ -604,9 +601,9 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) u4_regvalue); break; } - if (rtstatus != true) { + if (!rtstatus) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!", rfpath); goto phy_rf_cfg_fail; } @@ -620,7 +617,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) rtl92d_phy_powerdown_anotherphy(hw, false); else if (need_pwrdown_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; phy_rf_cfg_fail: diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h index 74b9cfc39a8..0fe1a48593e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 7911c9c8708..4898c502974 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,11 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/vmalloc.h> -#include <linux/module.h> - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -44,6 +39,8 @@ #include "trx.h" #include "led.h" +#include <linux/module.h> + static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -94,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) u8 tid; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; static int header_print; rtlpriv->dm.dm_initialgain_enable = true; @@ -154,9 +150,9 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; if (!rtlpriv->psc.inactiveps) - pr_info("rtl8192ce: Power Save off (module option)\n"); + pr_info("Power Save off (module option)\n"); if (!rtlpriv->psc.fwctrl_lps) - pr_info("rtl8192ce: FW Power Save off (module option)\n"); + pr_info("FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through @@ -170,41 +166,38 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) else if (rtlpriv->psc.reg_fwctrl_lps == 3) rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = true; + for (tid = 0; tid < 8; tid++) + skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + + /* Only load firmware for first MAC */ + if (header_print) + return 0; + /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } - if (!header_print) { - pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); - pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); - header_print++; - } + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); + pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); + header_print++; + /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); - return 1; - } - if (firmware->size > 0x8000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); - release_firmware(firmware); + "Failed to request firmware!\n"); return 1; } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); - /* for early mode */ - rtlpriv->rtlhal.earlymode_enable = true; - for (tid = 0; tid < 8; tid++) - skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); return 0; } @@ -424,7 +417,7 @@ static int __init rtl92de_module_init(void) ret = pci_register_driver(&rtl92de_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h index c95e47de134..0e6035b8fd8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/rtlwifi/rtl8192de/table.c index bad7f9449ec..8ea6f528dfa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/rtlwifi/rtl8192de/table.h index 93f30ca62d8..8b724a86117 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 3637c0c3352..a7f6126e2f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -602,8 +602,8 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, EM_HDR_LEN); if (ptcb_desc->empkt_num) { RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, - ("Insert 8 byte.pTcb->EMPktNum:%d\n", - ptcb_desc->empkt_num)); + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); _rtl92de_insert_emcontent(ptcb_desc, (u8 *)(skb->data)); } @@ -700,7 +700,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -726,7 +726,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_PKT_ID(pdesc, 8); } SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, @@ -776,7 +776,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE); + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); wmb(); SET_TX_DESC_OWN(pdesc, 1); } @@ -793,8 +793,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -813,8 +813,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -833,8 +833,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -847,8 +847,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_RX_DESC_PKT_LEN(pdesc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h index 4d55d0b6816..0dc736c2723 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h index c6c044816d3..d1b0a1e1497 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 4203a8531ca..fbabae17259 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -170,9 +170,9 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter( thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); if (thermalvalue) { rtlpriv->dm.thermalvalue = thermalvalue; @@ -282,11 +282,11 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) } if (ra->pre_ratr_state != ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld " - "RSSI_LEVEL = %d PreState = %d, CurState = %d\n", - rtlpriv->dm.undecorated_smoothed_pwdb, - ra->ratr_state, - ra->pre_ratr_state, ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", + rtlpriv->dm.undecorated_smoothed_pwdb, + ra->ratr_state, + ra->pre_ratr_state, ra->ratr_state); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, ra->ratr_state); @@ -586,7 +586,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; @@ -599,22 +599,22 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h index 9051a556acc..e1b19a64176 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 3fda6b1dcf4..380e7d4b1cc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -66,7 +66,7 @@ static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw) cpustatus = rtl_read_byte(rtlpriv, TCR); if (cpustatus & IMEM_RDY) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("IMEM Ready after CPU has refilled.\n")); + "IMEM Ready after CPU has refilled\n"); break; } @@ -120,9 +120,8 @@ static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw) return 0x22; break; default: - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Unknown RF type(%x)\n", - rtlphy->rf_type)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown RF type(%x)\n", + rtlphy->rf_type); break; } return 0x22; @@ -177,7 +176,7 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Size over FIRMWARE_CODE_SIZE!\n")); + "Size over FIRMWARE_CODE_SIZE!\n"); return false; } @@ -231,8 +230,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, short pollingcnt = 1000; bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n", - loadfw_status)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "LoadStaus(%d)\n", loadfw_status); firmware->fwstatus = (enum fw_status)loadfw_status; @@ -248,8 +247,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("FW_STATUS_LOAD_IMEM" - " FAIL CPU, Status=%x\r\n", cpustatus)); + "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n", + cpustatus); goto status_check_fail; } break; @@ -266,16 +265,16 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("FW_STATUS_LOAD_EMEM" - " FAIL CPU, Status=%x\r\n", cpustatus)); + "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n", + cpustatus); goto status_check_fail; } /* Turn On CPU */ rtstatus = _rtl92s_firmware_enable_cpu(hw); - if (rtstatus != true) { + if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Enable CPU fail!\n")); + "Enable CPU fail!\n"); goto status_check_fail; } break; @@ -291,14 +290,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling DMEM code done" - " fail ! cpustatus(%#x)\n", cpustatus)); + "Polling DMEM code done fail ! cpustatus(%#x)\n", + cpustatus); goto status_check_fail; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("DMEM code download success," - " cpustatus(%#x)\n", cpustatus)); + "DMEM code download success, cpustatus(%#x)\n", + cpustatus); /* Prevent Delay too much and being scheduled out */ /* Polling Load Firmware ready */ @@ -311,14 +310,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, } while (pollingcnt--); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Polling Load Firmware ready," - " cpustatus(%x)\n", cpustatus)); + "Polling Load Firmware ready, cpustatus(%x)\n", + cpustatus); if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling Load Firmware" - " ready fail ! cpustatus(%x)\n", cpustatus)); + "Polling Load Firmware ready fail ! cpustatus(%x)\n", + cpustatus); goto status_check_fail; } @@ -332,7 +331,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, RCR_APP_ICV | RCR_APP_MIC)); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Current RCR settings(%#x)\n", tmpu4b)); + "Current RCR settings(%#x)\n", tmpu4b); /* Set to normal mode. */ rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); @@ -340,14 +339,15 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, default: RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Unknown status check!\n")); + "Unknown status check!\n"); rtstatus = false; break; } status_check_fail: - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), " - "rtstatus(%x)\n", loadfw_status, rtstatus)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "loadfw_status(%d), rtstatus(%x)\n", + loadfw_status, rtstatus); return rtstatus; } @@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) u8 fwstatus = FW_STATUS_INIT; bool rtstatus = true; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; firmware = (struct rt_firmware *)rtlhal->pfirmware; @@ -378,17 +378,17 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) firmware->firmwareversion = byte(pfwheader->version, 0); firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:" - "%x, size:%x," - "imemsize:%x, sram size:%x\n", pfwheader->signature, + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", + pfwheader->signature, pfwheader->version, pfwheader->dmem_size, - pfwheader->img_imem_size, pfwheader->img_sram_size)); + pfwheader->img_imem_size, pfwheader->img_sram_size); /* 2. Retrieve IMEM image. */ if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > sizeof(firmware->fw_imem))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("memory for data image is less than IMEM required\n")); + "memory for data image is less than IMEM required\n"); goto fail; } else { puc_mappedfile += fwhdr_size; @@ -401,7 +401,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) /* 3. Retriecve EMEM image. */ if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("memory for data image is less than EMEM required\n")); + "memory for data image is less than EMEM required\n"); goto fail; } else { puc_mappedfile += firmware->fw_imem_len; @@ -436,7 +436,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unexpected Download step!!\n")); + "Unexpected Download step!!\n"); goto fail; break; } @@ -445,15 +445,15 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile, ul_filelength); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n"); goto fail; } /* <3> Check whether load FW process is ready */ rtstatus = _rtl92s_firmware_checkready(hw, fwstatus); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); + if (!rtstatus) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n"); goto fail; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h index 74cc503efe8..b4afff62643 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -30,6 +30,7 @@ #define __REALTEK_FIRMWARE92S_H__ #define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 +#define RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE 90000 #define RTL8190_CPU_START_OFFSET 0x80 /* Firmware Local buffer size. 64k */ #define MAX_FIRMWARE_CODE_SIZE 0xFF00 @@ -217,7 +218,7 @@ struct rt_firmware { u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE]; u32 fw_imem_len; u32 fw_emem_len; - u8 sz_fw_tmpbuffer[164000]; + u8 sz_fw_tmpbuffer[RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE]; u32 sz_fw_tmpbufferlen; u16 cmdpacket_fragthresold; }; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index c474486e391..b141c35bf92 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../efuse.h" #include "../base.h" @@ -80,8 +78,8 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } default: { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -140,7 +138,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); @@ -185,8 +183,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -201,8 +199,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -244,8 +242,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -282,8 +280,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -299,13 +297,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl)); + "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl); break; } @@ -404,7 +402,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -415,14 +413,14 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 sec_reg_value = 0x0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d " - "GroupEncAlgorithm = %d\n", + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open hw encryption\n")); + "not open hw encryption\n"); return; } @@ -433,8 +431,8 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) sec_reg_value |= SCR_RXUSEDK; } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n", - sec_reg_value)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -718,8 +716,8 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw) if (pollingcnt <= 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling TXDMA_INIT_VALUE " - "timeout!! Current TCR(%#x)\n", tmpu1b)); + "Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", + tmpu1b); tmpu1b = rtl_read_byte(rtlpriv, CMDR); rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN)); udelay(2); @@ -870,10 +868,10 @@ static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw) /* Change Program timing */ rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); } @@ -951,12 +949,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtstatus = rtl92s_download_fw(hw); if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. " - "Init HW without FW now.., Please copy FW into" - "/lib/firmware/rtlwifi\n")); - rtlhal->fw_ready = false; - } else { - rtlhal->fw_ready = true; + "Failed to download FW. Init HW without FW now... " + "Please copy FW into /lib/firmware/rtlwifi\n"); + return 1; } /* After FW download, we have to reset MAC register */ @@ -967,8 +962,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK); /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ - if (rtl92s_phy_mac_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n")); + if (!rtl92s_phy_mac_config(hw)) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n"); return rtstatus; } @@ -977,8 +972,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, CMDR, 0x37FC); /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ - if (rtl92s_phy_bb_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n")); + if (!rtl92s_phy_bb_config(hw)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n"); return rtstatus; } @@ -1013,8 +1008,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) else rtl_write_byte(rtlpriv, RF_CTRL, 0x07); - if (rtl92s_phy_rf_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n")); + if (!rtl92s_phy_rf_config(hw)) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); return rtstatus; } @@ -1110,7 +1105,7 @@ void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) if (check_bssid) { reg_rcr |= (RCR_CBSSID); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); - } else if (check_bssid == false) { + } else if (!check_bssid) { reg_rcr &= (~RCR_CBSSID); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); } @@ -1129,26 +1124,26 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1202,7 +1197,7 @@ void rtl92se_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } @@ -1219,9 +1214,14 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw) void rtl92se_disable_interrupt(struct ieee80211_hw *hw) { - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv; + struct rtl_pci *rtlpci; + rtlpriv = rtl_priv(hw); + /* if firmware not available, no interrupts */ + if (!rtlpriv || !rtlpriv->max_fw_size) + return; + rtlpci = rtl_pcidev(rtl_pcipriv(hw)); rtl_write_dword(rtlpriv, INTA_MASK, 0); rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); @@ -1583,8 +1583,8 @@ void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1627,7 +1627,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { rtl_efuse_shadow_map_update(hw); @@ -1636,16 +1636,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE_92S); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE_92S); eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1663,15 +1663,15 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROMId = 0x%4x\n", eeprom_id)); + "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; @@ -1681,8 +1681,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (i = 0; i < 6; i++) rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); /* Get Tx Power Level by Channel */ /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ @@ -1707,23 +1706,24 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif - [rf_path][i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { @@ -1754,11 +1754,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } @@ -1791,13 +1791,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) 0xf0) >> 4); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } @@ -1852,27 +1852,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) (hwinfo[EEPROM_REGULATORY] & 0x1); } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n", - rtlefuse->txpwr_safetyflag)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); /* Read RF-indication and Tx Power gain * index diff of legacy to HT OFDM rate. */ @@ -1881,8 +1881,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->legacy_httxpowerdiff = rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n", - rtlefuse->eeprom_txpowerdiff)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); /* Get TSSI value for each path. */ usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; @@ -1890,16 +1890,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B]; rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); /* Read antenna tx power offset of B/C/D to A from EEPROM */ /* and read ThermalMeter from EEPROM */ tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER]; rtlefuse->eeprom_thermalmeter = tempval; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n", - rtlefuse->eeprom_thermalmeter)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); @@ -1915,8 +1915,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) /* Version ID, Channel plan */ rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->txpwr_fromeprom = true; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n", - rtlefuse->eeprom_channelplan)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); /* Read Customer ID or Board Type!!! */ tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE]; @@ -1937,14 +1937,14 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) if (!(tempval & BIT(0))) { rtlefuse->b1x1_recvcombine = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("RF_TYPE=1T2R but only 1SS\n")); + "RF_TYPE=1T2R but only 1SS\n"); } } rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x", - rtlefuse->eeprom_oemid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x", + rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1959,19 +1959,19 @@ void rtl92se_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92se_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); rtlefuse->autoload_failflag = true; } } @@ -2071,8 +2071,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, else rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, ARFR0)); } static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2224,8 +2224,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); - RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n", - mask, ratr_bitmap)); + RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", + mask, ratr_bitmap); rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); @@ -2301,14 +2301,14 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("RFKILL-HW Radio ON, RF ON\n")); + "RFKILL-HW Radio ON, RF ON\n"); rfpwr_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; - } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("RFKILL-HW Radio OFF, RF OFF\n")); + } else if ((!ppsc->hwradiooff) && (rfpwr_toset == ERFOFF)) { + RT_TRACE(rtlpriv, COMP_RF, + DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); rfpwr_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2372,7 +2372,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2401,7 +2401,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2419,9 +2419,8 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, - COMP_SEC, DBG_EMERG, - ("Can not find free hw" - " security cam entry\n")); + COMP_SEC, DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2435,30 +2434,31 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", - rtlpriv->sec.pairwise_key, - rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + "Pairwise Key content", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2466,7 +2466,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, rtlpriv->sec.key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h index 6160a9bfe98..1886c2644a2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index e3fe7c90ebf..44949b5cbb8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -52,8 +52,8 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -68,7 +68,7 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -76,12 +76,15 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) { - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv; struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); + rtlpriv = rtl_priv(hw); + if (!rtlpriv || rtlpriv->max_fw_size) + return; + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -101,7 +104,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -141,8 +144,7 @@ void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92se_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h index 8cce3870af3..2182dbeb5f3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index f10ac1ad908..4a499928e4c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../pci.h" #include "../ps.h" @@ -58,16 +56,15 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue = 0, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n", - regaddr, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("BBR MASK=0x%x Addr[0x%x]=0x%x\n", - bitmask, regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -79,8 +76,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -90,8 +88,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } @@ -149,8 +148,8 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; @@ -172,8 +171,8 @@ static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } @@ -183,8 +182,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 original_value, readback_value, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x)\n", regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); @@ -195,9 +195,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, - bitmask, original_value)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -212,8 +212,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) return; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); @@ -228,8 +229,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " - "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } @@ -249,7 +251,7 @@ void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown operation.\n")); + "Unknown operation\n"); break; } } @@ -264,9 +266,9 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 reg_bw_opmode; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (rtlphy->set_bwmode_inprogress) return; @@ -290,8 +292,7 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", - rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } @@ -316,13 +317,13 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, @@ -332,7 +333,7 @@ static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } @@ -377,7 +378,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); + "invalid channel for Zebra: %d\n", channel); _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, @@ -438,7 +439,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -458,9 +459,8 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) u32 delay; bool ret; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", - rtlphy->current_channel)); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", + rtlphy->current_channel); if (rtlphy->sw_chnl_inprogress) return 0; @@ -496,7 +496,7 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) rtlphy->sw_chnl_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); return 1; } @@ -556,20 +556,19 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) && - (InitializeCount < 10)); + } while (!rtstatus && (InitializeCount < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("awake, sleeped:%d ms " - "state_inap:%x\n", - jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies), - rtlpriv->psc.state_inap)); + "awake, sleeped:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; rtl_write_word(rtlpriv, CMDR, 0x37FC); rtl_write_byte(rtlpriv, TXPAUSE, 0x00); @@ -587,7 +586,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -613,11 +612,9 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: " - "%d times TcbBusyQueue[%d] = " - "%d before doze!\n", - (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; @@ -625,31 +622,30 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times" - "TcbBusyQueue[%d] = %d !\n", + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", MAX_DOZE_WAITING_TIMES_9x, queue_id, - skb_queue_len(&ring->queue))); + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", + "Set ERFSLEEP awaked:%d ms\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + ppsc->last_awake_jiffies)); RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("sleep awaked:%d ms " - "state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), - rtlpriv->psc.state_inap)); + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92se_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } @@ -681,30 +677,28 @@ static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); + int index; if (reg_addr == RTXAGC_RATE18_06) - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = - data; - if (reg_addr == RTXAGC_RATE54_24) - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = - data; - if (reg_addr == RTXAGC_CCK_MCS32) - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = - data; - if (reg_addr == RTXAGC_MCS03_MCS00) - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = - data; - if (reg_addr == RTXAGC_MCS07_MCS04) - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = - data; - if (reg_addr == RTXAGC_MCS11_MCS08) - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = - data; - if (reg_addr == RTXAGC_MCS15_MCS12) { - rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = - data; + index = 0; + else if (reg_addr == RTXAGC_RATE54_24) + index = 1; + else if (reg_addr == RTXAGC_CCK_MCS32) + index = 6; + else if (reg_addr == RTXAGC_MCS03_MCS00) + index = 2; + else if (reg_addr == RTXAGC_MCS07_MCS04) + index = 3; + else if (reg_addr == RTXAGC_MCS11_MCS08) + index = 4; + else if (reg_addr == RTXAGC_MCS15_MCS12) + index = 5; + else + return; + + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; + if (index == 5) rtlphy->pwrgroup_cnt++; - } } static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) @@ -993,9 +987,9 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) rtstatus = false; } - if (rtstatus != true) { + if (!rtstatus) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Write BB Reg Fail!!")); + "Write BB Reg Fail!!\n"); goto phy_BB8190_Config_ParaFile_Fail; } @@ -1007,17 +1001,16 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) rtstatus = _rtl92s_phy_config_bb_with_pg(hw, BASEBAND_CONFIG_PHY_REG); } - if (rtstatus != true) { + if (!rtstatus) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("_rtl92s_phy_bb_config_parafile(): " - "BB_PG Reg Fail!!")); + "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n"); goto phy_BB8190_Config_ParaFile_Fail; } /* 3. BB AGC table Initialization */ rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { + if (!rtstatus) { pr_err("%s(): AGC Table Fail\n", __func__); goto phy_BB8190_Config_ParaFile_Fail; } @@ -1053,7 +1046,7 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) radio_b_tblen = RADIOB_ARRAYLENGTH; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); rtstatus = true; switch (rfpath) { @@ -1175,11 +1168,11 @@ bool rtl92s_phy_bb_config(struct ieee80211_hw *hw) (rtlphy->rf_type == RF_2T2R && rf_num != 2) || (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("RF_Type(%x) does not match " - "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num)); + "RF_Type(%x) does not match RF_Num(%x)!!\n", + rtlphy->rf_type, rf_num); RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("path1 0x%x, path2 0x%x, pathmap " - "0x%x\n", path1, path2, pathmap)); + "path1 0x%x, path2 0x%x, pathmap 0x%x\n", + path1, path2, pathmap); } return rtstatus; @@ -1214,20 +1207,20 @@ void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_XCAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain " - "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", rtlphy->default_initialgain[0], rtlphy->default_initialgain[1], rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + rtlphy->default_initialgain[3]); /* read framesync */ rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } @@ -1274,7 +1267,7 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) /* [0]:RF-A, [1]:RF-B */ u8 cckpowerlevel[2], ofdmpowerLevel[2]; - if (rtlefuse->txpwr_fromeprom == false) + if (!rtlefuse->txpwr_fromeprom) return; /* Mainly we use RF-A Tx Power to write the Tx Power registers, @@ -1287,10 +1280,9 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) &ofdmpowerLevel[0]); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Channel-%d, cckPowerLevel (A / B) = " - "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", - channel, cckpowerlevel[0], cckpowerlevel[1], - ofdmpowerLevel[0], ofdmpowerLevel[1])); + "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", + channel, cckpowerlevel[0], cckpowerlevel[1], + ofdmpowerLevel[0], ofdmpowerLevel[1]); _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], &ofdmpowerLevel[0]); @@ -1316,7 +1308,7 @@ void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) } while (--pollingcnt); if (pollingcnt == 0) - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n"); } @@ -1345,20 +1337,17 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) switch (rtlhal->current_fwcmd_io) { case FW_CMD_RA_RESET: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_RESET\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_ACTIVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_ACTIVE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_N: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_N\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); input = FW_RA_REFRESH; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); @@ -1367,7 +1356,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_RA_REFRESH_BG: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_BG\n")); + "FW_CMD_RA_REFRESH_BG\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); rtl92s_phy_chk_fwcmd_iodone(hw); rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); @@ -1375,21 +1364,20 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_RA_REFRESH_N_COMB: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_N_COMB\n")); + "FW_CMD_RA_REFRESH_N_COMB\n"); input = FW_RA_IOT_N_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_BG_COMB: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_BG_COMB\n")); + "FW_CMD_RA_REFRESH_BG_COMB\n"); input = FW_RA_IOT_BG_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_IQK_ENABLE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_IQK_ENABLE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1424,8 +1412,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); break; case FW_CMD_LPS_ENTER: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_LPS_ENTER\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); current_aid = rtlpriv->mac80211.assoc_id; rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | ((current_aid | 0xc000) << 8))); @@ -1434,20 +1421,18 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) * turbo mode until driver leave LPS */ break; case FW_CMD_LPS_LEAVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_LPS_LEAVE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_ADD_A2_ENTRY: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_ADD_A2_ENTRY\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_CTRL_DM_BY_DRIVER: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("FW_CMD_CTRL_DM_BY_DRIVER\n")); + "FW_CMD_CTRL_DM_BY_DRIVER\n"); rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1472,8 +1457,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) bool bPostProcessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", - fw_cmdio, rtlhal->set_fwcmd_inprogress)); + "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", + fw_cmdio, rtlhal->set_fwcmd_inprogress); do { /* We re-map to combined FW CMD ones if firmware version */ @@ -1501,7 +1486,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) * DM map table in the future. */ switch (fw_cmdio) { case FW_CMD_RA_INIT: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); fw_cmdmap |= FW_RA_INIT_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); /* Clear control flag to sync with FW. */ @@ -1509,7 +1494,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_DIG_DISABLE: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG disable!!\n")); + "Set DIG disable!!\n"); fw_cmdmap &= ~FW_DIG_ENABLE_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1517,14 +1502,14 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) case FW_CMD_DIG_RESUME: if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG enable or resume!!\n")); + "Set DIG enable or resume!!\n"); fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); } break; case FW_CMD_DIG_HALT: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG halt!!\n")); + "Set DIG halt!!\n"); fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1540,9 +1525,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) (rtlefuse->thermalmeter[0] << 16)); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set TxPwr tracking!! " - "FwCmdMap(%#x), FwParam(%#x)\n", - fw_cmdmap, fw_param)); + "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1563,9 +1547,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) fw_param &= FW_RA_PARAM_CLR; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("[FW CMD] [New Version] " - "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), " - "FwParam(%#x)\n", fw_cmdmap, fw_param)); + "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1635,7 +1618,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_HIGH_PWR_ENABLE: if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) && - (rtlpriv->dm.dynamic_txpower_enable != true)) { + !rtlpriv->dm.dynamic_txpower_enable) { fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1652,7 +1635,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_PAPE_CONTROL: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("[FW CMD] Set PAPE Control\n")); + "[FW CMD] Set PAPE Control\n"); fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h index 37e504af644..ac038777063 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index 11f125c030c..84d1181795b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 0ad50fe44aa..08c2f562512 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "reg.h" #include "def.h" @@ -123,13 +121,13 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel, } if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx " - "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], - p_final_pwridx[1])); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx " - "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], - p_final_pwridx[1])); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } } @@ -153,9 +151,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, ant_pwr_diff = -8; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Antenna Diff from RF-B " - "to RF-A = %d (0x%x)\n", ant_pwr_diff, - ant_pwr_diff & 0xf)); + "Antenna Diff from RF-B to RF-A = %d (0x%x)\n", + ant_pwr_diff, ant_pwr_diff & 0xf); ant_pwr_diff &= 0xf; } @@ -172,9 +169,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), u4reg_val); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Write BCD-Diff(0x%x) = 0x%x\n", - RFPGA0_TXGAINSTAGE, u4reg_val)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n", + RFPGA0_TXGAINSTAGE, u4reg_val); } static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, @@ -201,8 +197,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("RTK better performance, " - "writeval = 0x%x\n", writeval)); + "RTK better performance, writeval = 0x%x\n", writeval); break; case 1: /* Realtek regulatory increase power diff defined @@ -211,8 +206,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, writeval = ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Realtek regulatory, " - "40MHz, writeval = 0x%x\n", writeval)); + "Realtek regulatory, 40MHz, writeval = 0x%x\n", + writeval); } else { if (rtlphy->pwrgroup_cnt == 1) chnlgroup = 0; @@ -234,16 +229,15 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Realtek regulatory, " - "20MHz, writeval = 0x%x\n", writeval)); + "Realtek regulatory, 20MHz, writeval = 0x%x\n", + writeval); } break; case 2: /* Better regulatory don't increase any power diff */ writeval = ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Better regulatory, " - "writeval = 0x%x\n", writeval)); + "Better regulatory, writeval = 0x%x\n", writeval); break; case 3: /* Customer defined power diff. increase power diff @@ -252,14 +246,14 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("customer's limit, 40MHz = 0x%x\n", - rtlefuse->pwrgroup_ht40 - [RF90_PATH_A][chnl - 1])); + "customer's limit, 40MHz = 0x%x\n", + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("customer's limit, 20MHz = 0x%x\n", - rtlefuse->pwrgroup_ht20 - [RF90_PATH_A][chnl - 1])); + "customer's limit, 20MHz = 0x%x\n", + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]); } for (i = 0; i < 4; i++) { @@ -293,22 +287,19 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, (pwrdiff_limit[1] << 8) | (pwrdiff_limit[0]); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Customer's limit = 0x%x\n", - customer_limit)); + "Customer's limit = 0x%x\n", customer_limit); writeval = customer_limit + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Customer, writeval = " - "0x%x\n", writeval)); + "Customer, writeval = 0x%x\n", writeval); break; default: chnlgroup = 0; writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("RTK better performance, " - "writeval = 0x%x\n", writeval)); + "RTK better performance, writeval = 0x%x\n", writeval); break; } @@ -508,7 +499,7 @@ bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) break; } - if (rtstatus != true) { + if (!rtstatus) { pr_err("Radio[%d] Fail!!\n", rfpath); goto fail; } @@ -541,8 +532,7 @@ void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", - bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h index 3843baa1a87..8a29eb94ab1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 78723cf5949..f1b36005c6a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -27,14 +27,11 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/vmalloc.h> -#include <linux/module.h> - #include "../wifi.h" #include "../core.h" #include "../pci.h" +#include "../base.h" +#include "../pci.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -45,6 +42,8 @@ #include "trx.h" #include "led.h" +#include <linux/module.h> + static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); @@ -89,12 +88,54 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) rtlpci->const_support_pciaspm = 2; } +static void rtl92se_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + struct rt_firmware *pfirmware = NULL; + int err; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } + if (firmware->size > rtlpriv->max_fw_size) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Firmware is too big!\n"); + rtlpriv->max_fw_size = 0; + release_firmware(firmware); + return; + } + pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; + memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); + pfirmware->sz_fw_tmpbufferlen = firmware->size; + release_firmware(firmware); + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw\n"); + return; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + rtlpci->irq_alloc = 1; + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /*init rfkill */ + rtl_init_rfkill(hw); +} + static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; - struct rt_firmware *pfirmware = NULL; int err = 0; u16 earlyrxthreshold = 7; @@ -168,9 +209,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; if (!rtlpriv->psc.inactiveps) - pr_info("rtl8192ce: Power Save off (module option)\n"); + pr_info("Power Save off (module option)\n"); if (!rtlpriv->psc.fwctrl_lps) - pr_info("rtl8192ce: FW Power Save off (module option)\n"); + pr_info("FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through @@ -186,33 +227,22 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); - if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + if (!rtlpriv->rtlhal.pfirmware) return 1; - } + + rtlpriv->max_fw_size = RTL8190_MAX_RAW_FIRMWARE_CODE_SIZE; pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" "Loading firmware %s\n", rtlpriv->cfg->fw_name); /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl92se_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } - if (firmware->size > sizeof(struct rt_firmware)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); - release_firmware(firmware); - return 1; - } - - pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; - memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); - pfirmware->sz_fw_tmpbufferlen = firmware->size; - release_firmware(firmware); return err; } @@ -426,7 +456,7 @@ static int __init rtl92se_module_init(void) ret = pci_register_driver(&rtl92se_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h index fc4eb285a0a..2eb88862ebe 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c index 154185b3969..f1a73f75127 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h index b4ed6d951eb..2feb73b71a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Realtek Corporation. All rights reserved. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index fbebe3ea0a2..2fd3d13b7ce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -756,7 +756,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, /* DOWRD 8 */ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, @@ -823,8 +823,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -843,8 +843,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_STATUS_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -863,8 +863,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -876,8 +876,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) ret = GET_RX_STATUS_DESC_PKT_LEN(desc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h index 05862c51b86..011e7b0695f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e956fa71d04..2e1e352864b 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -25,16 +25,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/usb.h> -#include <linux/export.h> -#include "core.h" #include "wifi.h" +#include "core.h" #include "usb.h" #include "base.h" #include "ps.h" #include "rtl8192c/fw_common.h" +#include <linux/export.h> #define REALTEK_USB_VENQT_READ 0xC0 #define REALTEK_USB_VENQT_WRITE 0x40 @@ -276,14 +273,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw) ? USB_HIGH_SPEED_BULK_SIZE : USB_FULL_SPEED_BULK_SIZE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); for (i = 0; i < __RTL_TXQ_NUM; i++) { u32 ep_num = rtlusb->ep_map.ep_mapping[i]; if (!ep_num) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Invalid endpoint map setting!\n")); + "Invalid endpoint map setting!\n"); return -EINVAL; } } @@ -345,13 +342,18 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) rtlusb->out_ep_nums++; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval)); + pep_desc->bInterval); + } + if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { + pr_err("Too few input end points found\n"); + return -EINVAL; + } + if (rtlusb->out_ep_nums == 0) { + pr_err("No output end points found\n"); + return -EINVAL; } - if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) - return -EINVAL ; - /* usb endpoint mapping */ err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; @@ -360,7 +362,7 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) return err; } -static int _rtl_usb_init_sw(struct ieee80211_hw *hw) +static void rtl_usb_init_sw(struct ieee80211_hw *hw) { struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); @@ -395,7 +397,6 @@ static int _rtl_usb_init_sw(struct ieee80211_hw *hw) /* HIMR_EX - turn all on */ rtlusb->irq_mask[1] = 0xFFFFFFFF; rtlusb->disableHWSM = true; - return 0; } #define __RADIO_TAP_SIZE_RSV 32 @@ -414,7 +415,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, gfp_mask); if (!skb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")) + "Failed to __dev_alloc_skb!!\n"); return ERR_PTR(-ENOMEM); } @@ -520,12 +521,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, u8 *pdata; uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, - sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); + if (uskb) { /* drop packet on allocation failure */ + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + ieee80211_rx_irqsafe(hw, uskb); + } dev_kfree_skb_any(skb); - ieee80211_rx_irqsafe(hw, uskb); } else { dev_kfree_skb_any(skb); } @@ -575,7 +578,7 @@ static void _rtl_rx_completed(struct urb *_urb) if (IS_ERR(_skb)) { err = PTR_ERR(_skb); RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate skb for bulk IN!\n")); + "Can't allocate skb for bulk IN!\n"); return; } skb = _skb; @@ -632,14 +635,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")) + "Failed to alloc URB!!\n"); goto err_out; } skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); if (IS_ERR(skb)) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")) + "Failed to prep_rx_urb!!\n"); err = PTR_ERR(skb); goto err_out; } @@ -665,15 +668,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw) struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); err = rtlpriv->cfg->ops->hw_init(hw); - rtl_init_rx_config(hw); + if (!err) { + rtl_init_rx_config(hw); - /* Enable software */ - SET_USB_START(rtlusb); - /* should after adapter start and interrupt enable. */ - set_hal_start(rtlhal); + /* Enable software */ + SET_USB_START(rtlusb); + /* should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); - /* Start bulk IN */ - _rtl_usb_receive(hw); + /* Start bulk IN */ + _rtl_usb_receive(hw); + } return err; } @@ -745,7 +750,7 @@ static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) struct sk_buff *skb; RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to submit urb.\n")); + "Failed to submit urb\n"); usb_unanchor_urb(_urb); skb = (struct sk_buff *)_urb->context; kfree_skb(skb); @@ -768,7 +773,7 @@ static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, if (urb->status) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Urb has error status 0x%X\n", urb->status)); + "Urb has error status 0x%X\n", urb->status); goto out; } /* TODO: statistics */ @@ -805,7 +810,7 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, _urb = usb_alloc_urb(0, GFP_ATOMIC); if (!_urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate URB for bulk out!\n")); + "Can't allocate URB for bulk out!\n"); kfree_skb(skb); return NULL; } @@ -830,7 +835,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); if (unlikely(IS_USB_STOP(rtlusb))) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("USB device is stopping...\n")); + "USB device is stopping...\n"); kfree_skb(skb); return; } @@ -840,7 +845,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate urb. Drop skb!\n")); + "Can't allocate urb. Drop skb!\n"); return; } urb_list = &rtlusb->tx_pending[ep_num]; @@ -865,7 +870,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -946,10 +951,11 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + sizeof(struct rtl_usb_priv), &rtl_ops); if (!hw) { - RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); + RT_ASSERT(false, "ieee80211 alloc failed\n"); return -ENOMEM; } rtlpriv = hw->priv; + init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); udev = interface_to_usbdev(intf); usb_get_dev(udev); @@ -969,39 +975,28 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, /*like read eeprom and so on */ rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto error_out; } rtlpriv->cfg->ops->init_sw_leds(hw); err = _rtl_usb_init(hw); - err = _rtl_usb_init_sw(hw); + if (err) + goto error_out; + rtl_usb_init_sw(hw); /* Init mac80211 sw */ err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto error_out; } - /*init rfkill */ - /* rtl_init_rfkill(hw); */ - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Can't register mac80211 hw.\n")); - goto error_out; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; error_out: rtl_deinit_core(hw); _rtl_usb_io_handler_release(hw); - ieee80211_free_hw(hw); usb_put_dev(udev); + complete(&rtlpriv->firmware_loading_complete); return -ENODEV; } EXPORT_SYMBOL(rtl_usb_probe); @@ -1015,6 +1010,9 @@ void rtl_usb_disconnect(struct usb_interface *intf) if (unlikely(!rtlpriv)) return; + + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); /*ieee80211_unregister_hw will call ops_stop */ if (rtlmac->mac80211_registered == 1) { ieee80211_unregister_hw(hw); diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index d2a63fb3e1e..43846b32915 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek 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 @@ -28,7 +28,6 @@ #ifndef __RTL_USB_H__ #define __RTL_USB_H__ -#include <linux/usb.h> #include <linux/skbuff.h> #define RTL_RX_DESC_SIZE 24 diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index cdaf1429fa0..b591614c3b9 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * 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 @@ -30,12 +30,15 @@ #ifndef __RTL_WIFI_H__ #define __RTL_WIFI_H__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/sched.h> #include <linux/firmware.h> #include <linux/etherdevice.h> #include <linux/vmalloc.h> #include <linux/usb.h> #include <net/mac80211.h> +#include <linux/completion.h> #include "debug.h" #define RF_CHANGE_BY_INIT 0 @@ -1045,7 +1048,6 @@ struct rtl_hal { u16 fw_subversion; bool h2c_setinprogress; u8 last_hmeboxnum; - bool fw_ready; /*Reserve page start offset except beacon in TxQ. */ u8 fw_rsvdpage_startoffset; u8 h2c_txcmd_seq; @@ -1591,6 +1593,7 @@ struct rtl_debug { }; struct rtl_priv { + struct completion firmware_loading_complete; struct rtl_locks locks; struct rtl_works works; struct rtl_mac mac80211; @@ -1612,6 +1615,7 @@ struct rtl_priv { struct rtl_rate_priv *rate_priv; struct rtl_debug dbg; + int max_fw_size; /* *hal_cfg : for diff cards diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile index 58b4f935a3f..a5c6328b5f7 100644 --- a/drivers/net/wireless/wl1251/Makefile +++ b/drivers/net/wireless/wl1251/Makefile @@ -6,3 +6,5 @@ wl1251_sdio-objs += sdio.o obj-$(CONFIG_WL1251) += wl1251.o obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/wl1251/boot.c b/drivers/net/wireless/wl1251/boot.c index d729daf8e84..a2e5241382d 100644 --- a/drivers/net/wireless/wl1251/boot.c +++ b/drivers/net/wireless/wl1251/boot.c @@ -464,8 +464,6 @@ static int wl1251_boot_upload_nvs(struct wl1251 *wl) val = (nvs_ptr[0] | (nvs_ptr[1] << 8) | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24)); - val = cpu_to_le32(val); - wl1251_debug(DEBUG_BOOT, "nvs write table 0x%x: 0x%x", nvs_start, val); diff --git a/drivers/net/wireless/wl1251/io.h b/drivers/net/wireless/wl1251/io.h index c545e9d5f51..d382877c34c 100644 --- a/drivers/net/wireless/wl1251/io.h +++ b/drivers/net/wireless/wl1251/io.h @@ -36,16 +36,15 @@ static inline u32 wl1251_read32(struct wl1251 *wl, int addr) { - u32 response; - - wl->if_ops->read(wl, addr, &response, sizeof(u32)); + wl->if_ops->read(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32)); - return response; + return le32_to_cpu(wl->buffer_32); } static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val) { - wl->if_ops->write(wl, addr, &val, sizeof(u32)); + wl->buffer_32 = cpu_to_le32(val); + wl->if_ops->write(wl, addr, &wl->buffer_32, sizeof(wl->buffer_32)); } static inline u32 wl1251_read_elp(struct wl1251 *wl, int addr) diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index ba3268ea81f..41302c7b1ad 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -514,6 +514,9 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, struct wl1251 *wl = hw->priv; int ret = 0; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", vif->type, vif->addr); @@ -1338,9 +1341,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_BEACON_FILTER | - IEEE80211_HW_SUPPORTS_UAPSD | - IEEE80211_HW_SUPPORTS_CQM_RSSI; + IEEE80211_HW_SUPPORTS_UAPSD; wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/wl1251/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h index a77f1bbbed0..9d8f5816c6f 100644 --- a/drivers/net/wireless/wl1251/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -380,7 +380,7 @@ struct wl1251 { struct wl1251_stats stats; struct wl1251_debugfs debugfs; - u32 buffer_32; + __le32 buffer_32; u32 buffer_cmd; u8 buffer_busyword[WL1251_BUSY_WORD_LEN]; struct wl1251_rx_descriptor *rx_descriptor; diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index fe67262ba19..98f289c907a 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_WL12XX_SDIO) += wl12xx_sdio.o # small builtin driver bit obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 7537c401a44..bc96db0683a 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -34,12 +34,14 @@ #include "reg.h" #include "ps.h" -int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif) +int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif, + u8 wake_up_event, u8 listen_interval) { struct acx_wake_up_condition *wake_up; int ret; - wl1271_debug(DEBUG_ACX, "acx wake up conditions"); + wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)", + wake_up_event, listen_interval); wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); if (!wake_up) { @@ -48,8 +50,8 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif) } wake_up->role_id = wlvif->role_id; - wake_up->wake_up_event = wl->conf.conn.wake_up_event; - wake_up->listen_interval = wl->conf.conn.listen_interval; + wake_up->wake_up_event = wake_up_event; + wake_up->listen_interval = listen_interval; ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS, wake_up, sizeof(*wake_up)); @@ -1459,9 +1461,10 @@ out: return ret; } -int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) +int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif, + u64 *mactime) { - struct wl1271_acx_fw_tsf_information *tsf_info; + struct wl12xx_acx_fw_tsf_information *tsf_info; int ret; tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); @@ -1470,6 +1473,8 @@ int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime) goto out; } + tsf_info->role_id = wlvif->role_id; + ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, tsf_info, sizeof(*tsf_info)); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 69892b40c2d..a28fc044034 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -995,15 +995,17 @@ struct wl1271_acx_ba_receiver_setup { u8 padding[2]; } __packed; -struct wl1271_acx_fw_tsf_information { +struct wl12xx_acx_fw_tsf_information { struct acx_header header; + u8 role_id; + u8 padding1[3]; __le32 current_tsf_high; __le32 current_tsf_low; __le32 last_bttt_high; __le32 last_tbtt_low; u8 last_dtim_count; - u8 padding[3]; + u8 padding2[3]; } __packed; struct wl1271_acx_ps_rx_streaming { @@ -1151,79 +1153,81 @@ struct wl12xx_acx_config_hangover { } __packed; enum { - ACX_WAKE_UP_CONDITIONS = 0x0002, - ACX_MEM_CFG = 0x0003, - ACX_SLOT = 0x0004, - ACX_AC_CFG = 0x0007, - ACX_MEM_MAP = 0x0008, - ACX_AID = 0x000A, - ACX_MEDIUM_USAGE = 0x000F, - ACX_TX_QUEUE_CFG = 0x0011, /* FIXME: only used by wl1251 */ - ACX_STATISTICS = 0x0013, /* Debug API */ - ACX_PWR_CONSUMPTION_STATISTICS = 0x0014, - ACX_FEATURE_CFG = 0x0015, - ACX_TID_CFG = 0x001A, - ACX_PS_RX_STREAMING = 0x001B, - ACX_BEACON_FILTER_OPT = 0x001F, - ACX_NOISE_HIST = 0x0021, - ACX_HDK_VERSION = 0x0022, /* ??? */ - ACX_PD_THRESHOLD = 0x0023, - ACX_TX_CONFIG_OPT = 0x0024, - ACX_CCA_THRESHOLD = 0x0025, - ACX_EVENT_MBOX_MASK = 0x0026, - ACX_CONN_MONIT_PARAMS = 0x002D, - ACX_BCN_DTIM_OPTIONS = 0x0031, - ACX_SG_ENABLE = 0x0032, - ACX_SG_CFG = 0x0033, - ACX_FM_COEX_CFG = 0x0034, - ACX_BEACON_FILTER_TABLE = 0x0038, - ACX_ARP_IP_FILTER = 0x0039, - ACX_ROAMING_STATISTICS_TBL = 0x003B, - ACX_RATE_POLICY = 0x003D, - ACX_CTS_PROTECTION = 0x003E, - ACX_SLEEP_AUTH = 0x003F, - ACX_PREAMBLE_TYPE = 0x0040, - ACX_ERROR_CNT = 0x0041, - ACX_IBSS_FILTER = 0x0044, - ACX_SERVICE_PERIOD_TIMEOUT = 0x0045, - ACX_TSF_INFO = 0x0046, - ACX_CONFIG_PS_WMM = 0x0049, - ACX_ENABLE_RX_DATA_FILTER = 0x004A, - ACX_SET_RX_DATA_FILTER = 0x004B, - ACX_GET_DATA_FILTER_STATISTICS = 0x004C, - ACX_RX_CONFIG_OPT = 0x004E, - ACX_FRAG_CFG = 0x004F, - ACX_BET_ENABLE = 0x0050, - ACX_RSSI_SNR_TRIGGER = 0x0051, - ACX_RSSI_SNR_WEIGHTS = 0x0052, - ACX_KEEP_ALIVE_MODE = 0x0053, - ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, - ACX_BA_SESSION_INIT_POLICY = 0x0055, - ACX_BA_SESSION_RX_SETUP = 0x0056, - ACX_PEER_HT_CAP = 0x0057, - ACX_HT_BSS_OPERATION = 0x0058, - ACX_COEX_ACTIVITY = 0x0059, - ACX_BURST_MODE = 0x005C, - ACX_SET_RATE_MGMT_PARAMS = 0x005D, - ACX_SET_RATE_ADAPT_PARAMS = 0x0060, - ACX_SET_DCO_ITRIM_PARAMS = 0x0061, - ACX_GEN_FW_CMD = 0x0070, - ACX_HOST_IF_CFG_BITMAP = 0x0071, - ACX_MAX_TX_FAILURE = 0x0072, - ACX_UPDATE_INCONNECTION_STA_LIST = 0x0073, - DOT11_RX_MSDU_LIFE_TIME = 0x1004, - DOT11_CUR_TX_PWR = 0x100D, - DOT11_RX_DOT11_MODE = 0x1012, - DOT11_RTS_THRESHOLD = 0x1013, - DOT11_GROUP_ADDRESS_TBL = 0x1014, - ACX_PM_CONFIG = 0x1016, - ACX_CONFIG_PS = 0x1017, - ACX_CONFIG_HANGOVER = 0x1018, + ACX_WAKE_UP_CONDITIONS = 0x0000, + ACX_MEM_CFG = 0x0001, + ACX_SLOT = 0x0002, + ACX_AC_CFG = 0x0003, + ACX_MEM_MAP = 0x0004, + ACX_AID = 0x0005, + ACX_MEDIUM_USAGE = 0x0006, + ACX_STATISTICS = 0x0007, + ACX_PWR_CONSUMPTION_STATISTICS = 0x0008, + ACX_TID_CFG = 0x0009, + ACX_PS_RX_STREAMING = 0x000A, + ACX_BEACON_FILTER_OPT = 0x000B, + ACX_NOISE_HIST = 0x000C, + ACX_HDK_VERSION = 0x000D, + ACX_PD_THRESHOLD = 0x000E, + ACX_TX_CONFIG_OPT = 0x000F, + ACX_CCA_THRESHOLD = 0x0010, + ACX_EVENT_MBOX_MASK = 0x0011, + ACX_CONN_MONIT_PARAMS = 0x0012, + ACX_DISABLE_BROADCASTS = 0x0013, + ACX_BCN_DTIM_OPTIONS = 0x0014, + ACX_SG_ENABLE = 0x0015, + ACX_SG_CFG = 0x0016, + ACX_FM_COEX_CFG = 0x0017, + ACX_BEACON_FILTER_TABLE = 0x0018, + ACX_ARP_IP_FILTER = 0x0019, + ACX_ROAMING_STATISTICS_TBL = 0x001A, + ACX_RATE_POLICY = 0x001B, + ACX_CTS_PROTECTION = 0x001C, + ACX_SLEEP_AUTH = 0x001D, + ACX_PREAMBLE_TYPE = 0x001E, + ACX_ERROR_CNT = 0x001F, + ACX_IBSS_FILTER = 0x0020, + ACX_SERVICE_PERIOD_TIMEOUT = 0x0021, + ACX_TSF_INFO = 0x0022, + ACX_CONFIG_PS_WMM = 0x0023, + ACX_ENABLE_RX_DATA_FILTER = 0x0024, + ACX_SET_RX_DATA_FILTER = 0x0025, + ACX_GET_DATA_FILTER_STATISTICS = 0x0026, + ACX_RX_CONFIG_OPT = 0x0027, + ACX_FRAG_CFG = 0x0028, + ACX_BET_ENABLE = 0x0029, + ACX_RSSI_SNR_TRIGGER = 0x002A, + ACX_RSSI_SNR_WEIGHTS = 0x002B, + ACX_KEEP_ALIVE_MODE = 0x002C, + ACX_SET_KEEP_ALIVE_CONFIG = 0x002D, + ACX_BA_SESSION_INIT_POLICY = 0x002E, + ACX_BA_SESSION_RX_SETUP = 0x002F, + ACX_PEER_HT_CAP = 0x0030, + ACX_HT_BSS_OPERATION = 0x0031, + ACX_COEX_ACTIVITY = 0x0032, + ACX_BURST_MODE = 0x0033, + ACX_SET_RATE_MGMT_PARAMS = 0x0034, + ACX_GET_RATE_MGMT_PARAMS = 0x0035, + ACX_SET_RATE_ADAPT_PARAMS = 0x0036, + ACX_SET_DCO_ITRIM_PARAMS = 0x0037, + ACX_GEN_FW_CMD = 0x0038, + ACX_HOST_IF_CFG_BITMAP = 0x0039, + ACX_MAX_TX_FAILURE = 0x003A, + ACX_UPDATE_INCONNECTION_STA_LIST = 0x003B, + DOT11_RX_MSDU_LIFE_TIME = 0x003C, + DOT11_CUR_TX_PWR = 0x003D, + DOT11_RTS_THRESHOLD = 0x003E, + DOT11_GROUP_ADDRESS_TBL = 0x003F, + ACX_PM_CONFIG = 0x0040, + ACX_CONFIG_PS = 0x0041, + ACX_CONFIG_HANGOVER = 0x0042, + ACX_FEATURE_CFG = 0x0043, + ACX_PROTECTION_CFG = 0x0044, }; int wl1271_acx_wake_up_conditions(struct wl1271 *wl, - struct wl12xx_vif *wlvif); + struct wl12xx_vif *wlvif, + u8 wake_up_event, u8 listen_interval); int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth); int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif, int power); @@ -1296,7 +1300,8 @@ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl, struct wl12xx_vif *wlvif); int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, bool enable, u8 peer_hlid); -int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); +int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif, + u64 *mactime); int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool enable); int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif); diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 8f9cf5a816e..954101d03f0 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c @@ -33,65 +33,6 @@ #include "event.h" #include "rx.h" -static struct wl1271_partition_set part_table[PART_TABLE_LEN] = { - [PART_DOWN] = { - .mem = { - .start = 0x00000000, - .size = 0x000177c0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x00008800 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - }, - }, - - [PART_WORK] = { - .mem = { - .start = 0x00040000, - .size = 0x00014fc0 - }, - .reg = { - .start = REGISTERS_BASE, - .size = 0x0000a000 - }, - .mem2 = { - .start = 0x003004f8, - .size = 0x00000004 - }, - .mem3 = { - .start = 0x00040404, - .size = 0x00000000 - }, - }, - - [PART_DRPW] = { - .mem = { - .start = 0x00040000, - .size = 0x00014fc0 - }, - .reg = { - .start = DRPW_BASE, - .size = 0x00006000 - }, - .mem2 = { - .start = 0x00000000, - .size = 0x00000000 - }, - .mem3 = { - .start = 0x00000000, - .size = 0x00000000 - } - } -}; - static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) { u32 cpu_ctrl; @@ -181,13 +122,13 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, return -ENOMEM; } - memcpy(&partition, &part_table[PART_DOWN], sizeof(partition)); + memcpy(&partition, &wl12xx_part_table[PART_DOWN], sizeof(partition)); partition.mem.start = dest; wl1271_set_partition(wl, &partition); /* 10.1 set partition limit and chunk num */ chunk_num = 0; - partition_limit = part_table[PART_DOWN].mem.size; + partition_limit = wl12xx_part_table[PART_DOWN].mem.size; while (chunk_num < fw_data_len / CHUNK_SIZE) { /* 10.2 update partition, if needed */ @@ -195,7 +136,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, if (addr > partition_limit) { addr = dest + chunk_num * CHUNK_SIZE; partition_limit = chunk_num * CHUNK_SIZE + - part_table[PART_DOWN].mem.size; + wl12xx_part_table[PART_DOWN].mem.size; partition.mem.start = addr; wl1271_set_partition(wl, &partition); } @@ -317,12 +258,12 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) } /* update current MAC address to NVS */ - nvs_ptr[11] = wl->mac_addr[0]; - nvs_ptr[10] = wl->mac_addr[1]; - nvs_ptr[6] = wl->mac_addr[2]; - nvs_ptr[5] = wl->mac_addr[3]; - nvs_ptr[4] = wl->mac_addr[4]; - nvs_ptr[3] = wl->mac_addr[5]; + nvs_ptr[11] = wl->addresses[0].addr[0]; + nvs_ptr[10] = wl->addresses[0].addr[1]; + nvs_ptr[6] = wl->addresses[0].addr[2]; + nvs_ptr[5] = wl->addresses[0].addr[3]; + nvs_ptr[4] = wl->addresses[0].addr[4]; + nvs_ptr[3] = wl->addresses[0].addr[5]; /* * Layout before the actual NVS tables: @@ -383,7 +324,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) nvs_len -= nvs_ptr - (u8 *)wl->nvs; /* Now we must set the partition correctly */ - wl1271_set_partition(wl, &part_table[PART_WORK]); + wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]); /* Copy the NVS tables to a new block to ensure alignment */ nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); @@ -492,7 +433,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) wl->event_box_addr = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR); /* set the working partition to its "running" mode offset */ - wl1271_set_partition(wl, &part_table[PART_WORK]); + wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]); wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x", wl->cmd_box_addr, wl->event_box_addr); @@ -507,8 +448,7 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) /* unmask required mbox events */ wl->event_mask = BSS_LOSE_EVENT_ID | SCAN_COMPLETE_EVENT_ID | - PS_REPORT_EVENT_ID | - DISCONNECT_EVENT_COMPLETE_ID | + ROLE_STOP_COMPLETE_EVENT_ID | RSSI_SNR_TRIGGER_0_EVENT_ID | PSPOLL_DELIVERY_FAILURE_EVENT_ID | SOFT_GEMINI_SENSE_EVENT_ID | @@ -547,19 +487,6 @@ static int wl1271_boot_write_irq_polarity(struct wl1271 *wl) return 0; } -static void wl1271_boot_hw_version(struct wl1271 *wl) -{ - u32 fuse; - - if (wl->chip.id == CHIP_ID_1283_PG20) - fuse = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1); - else - fuse = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1); - fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; - - wl->hw_pg_ver = (s8)fuse; -} - static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) { u16 spare_reg; @@ -698,7 +625,7 @@ static int wl127x_boot_clk(struct wl1271 *wl) u32 pause; u32 clk; - if (((wl->hw_pg_ver & PG_MAJOR_VER_MASK) >> PG_MAJOR_VER_OFFSET) < 3) + if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; if (wl->ref_clock == CONF_REF_CLK_19_2_E || @@ -753,8 +680,6 @@ int wl1271_load_firmware(struct wl1271 *wl) u32 tmp, clk; int selected_clock = -1; - wl1271_boot_hw_version(wl); - if (wl->chip.id == CHIP_ID_1283_PG20) { ret = wl128x_boot_clk(wl, &selected_clock); if (ret < 0) @@ -769,7 +694,7 @@ int wl1271_load_firmware(struct wl1271 *wl) wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); udelay(500); - wl1271_set_partition(wl, &part_table[PART_DRPW]); + wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]); /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW. The RTRIM value will be added by the FW @@ -788,7 +713,7 @@ int wl1271_load_firmware(struct wl1271 *wl) wl1271_write32(wl, DRPW_SCRATCH_START, clk); - wl1271_set_partition(wl, &part_table[PART_WORK]); + wl1271_set_partition(wl, &wl12xx_part_table[PART_WORK]); /* Disable interrupts */ wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index 06dad9380fa..c3adc09f403 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h @@ -55,16 +55,6 @@ struct wl1271_static_data { #define OCP_REG_CLK_POLARITY 0x0cb2 #define OCP_REG_CLK_PULL 0x0cb4 -#define WL127X_REG_FUSE_DATA_2_1 0x050a -#define WL128X_REG_FUSE_DATA_2_1 0x2152 -#define PG_VER_MASK 0x3c -#define PG_VER_OFFSET 2 - -#define PG_MAJOR_VER_MASK 0x3 -#define PG_MAJOR_VER_OFFSET 0x0 -#define PG_MINOR_VER_MASK 0xc -#define PG_MINOR_VER_OFFSET 0x2 - #define CMD_MBOX_ADDRESS 0x407B4 #define POLARITY_LOW BIT(1) diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 25990bd38be..3414fc11e9b 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c @@ -459,23 +459,39 @@ out: int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) { + unsigned long flags; u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); if (link >= WL12XX_MAX_LINKS) return -EBUSY; + /* these bits are used by op_tx */ + spin_lock_irqsave(&wl->wl_lock, flags); __set_bit(link, wl->links_map); __set_bit(link, wlvif->links_map); + spin_unlock_irqrestore(&wl->wl_lock, flags); *hlid = link; return 0; } void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) { + unsigned long flags; + if (*hlid == WL12XX_INVALID_LINK_ID) return; + /* these bits are used by op_tx */ + spin_lock_irqsave(&wl->wl_lock, flags); __clear_bit(*hlid, wl->links_map); __clear_bit(*hlid, wlvif->links_map); + spin_unlock_irqrestore(&wl->wl_lock, flags); + + /* + * At this point op_tx() will not add more packets to the queues. We + * can purge them. + */ + wl1271_tx_reset_link_queues(wl, *hlid); + *hlid = WL12XX_INVALID_LINK_ID; } @@ -515,7 +531,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, goto out_free; } cmd->device.hlid = wlvif->dev_hlid; - cmd->device.session = wlvif->session_counter; + cmd->device.session = wl12xx_get_new_session_id(wl, wlvif); wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d", cmd->role_id, cmd->device.hlid, cmd->device.session); @@ -566,7 +582,7 @@ static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, goto out_free; } - ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID); + ret = wl1271_cmd_wait_for_event(wl, ROLE_STOP_COMPLETE_EVENT_ID); if (ret < 0) { wl1271_error("cmd role stop dev event completion error"); goto out_free; @@ -715,6 +731,8 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int); cmd->ap.dtim_interval = bss_conf->dtim_period; cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP; + /* FIXME: Change when adding DFS */ + cmd->ap.reset_tsf = 1; /* By default reset AP TSF */ cmd->channel = wlvif->channel; if (!bss_conf->hidden_ssid) { @@ -994,7 +1012,7 @@ out: } int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, - u8 ps_mode) + u8 ps_mode, u16 auto_ps_timeout) { struct wl1271_cmd_ps_params *ps_params = NULL; int ret = 0; @@ -1009,6 +1027,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, ps_params->role_id = wlvif->role_id; ps_params->ps_mode = ps_mode; + ps_params->auto_ps_timeout = auto_ps_timeout; ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, sizeof(*ps_params), 0); @@ -1022,13 +1041,15 @@ out: return ret; } -int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, - void *buf, size_t buf_len, int index, u32 rates) +int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, + u16 template_id, void *buf, size_t buf_len, + int index, u32 rates) { struct wl1271_cmd_template_set *cmd; int ret = 0; - wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id); + wl1271_debug(DEBUG_CMD, "cmd template_set %d (role %d)", + template_id, role_id); WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE); buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE); @@ -1039,6 +1060,8 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, goto out; } + /* during initialization wlvif is NULL */ + cmd->role_id = role_id; cmd->len = cpu_to_le16(buf_len); cmd->template_type = template_id; cmd->enabled_rates = cpu_to_le32(rates); @@ -1082,7 +1105,8 @@ int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif) ptr = skb->data; } - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_NULL_DATA, ptr, size, 0, wlvif->basic_rate); out: @@ -1105,7 +1129,7 @@ int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl, if (!skb) goto out; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV, skb->data, skb->len, CMD_TEMPL_KLV_IDX_NULL_DATA, wlvif->basic_rate); @@ -1130,7 +1154,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (!skb) goto out; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_PS_POLL, skb->data, skb->len, 0, wlvif->basic_rate_set); out: @@ -1138,9 +1163,10 @@ out: return ret; } -int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, +int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, + u8 role_id, u8 band, const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band) + const u8 *ie, size_t ie_len) { struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); struct sk_buff *skb; @@ -1158,10 +1184,12 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]); if (band == IEEE80211_BAND_2GHZ) - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, + ret = wl1271_cmd_template_set(wl, role_id, + CMD_TEMPL_CFG_PROBE_REQ_2_4, skb->data, skb->len, 0, rate); else - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + ret = wl1271_cmd_template_set(wl, role_id, + CMD_TEMPL_CFG_PROBE_REQ_5, skb->data, skb->len, 0, rate); out: @@ -1186,10 +1214,12 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]); if (wlvif->band == IEEE80211_BAND_2GHZ) - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_CFG_PROBE_REQ_2_4, skb->data, skb->len, 0, rate); else - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_CFG_PROBE_REQ_5, skb->data, skb->len, 0, rate); if (ret < 0) @@ -1199,32 +1229,34 @@ out: return skb; } -int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif, - __be32 ip_addr) +int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif) { - int ret; + int ret, extra; + u16 fc; struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); - struct wl12xx_arp_rsp_template tmpl; + struct sk_buff *skb; + struct wl12xx_arp_rsp_template *tmpl; struct ieee80211_hdr_3addr *hdr; struct arphdr *arp_hdr; - memset(&tmpl, 0, sizeof(tmpl)); + skb = dev_alloc_skb(sizeof(*hdr) + sizeof(__le16) + sizeof(*tmpl) + + WL1271_EXTRA_SPACE_MAX); + if (!skb) { + wl1271_error("failed to allocate buffer for arp rsp template"); + return -ENOMEM; + } - /* mac80211 header */ - hdr = &tmpl.hdr; - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | - IEEE80211_STYPE_DATA | - IEEE80211_FCTL_TODS); - memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN); - memcpy(hdr->addr2, vif->addr, ETH_ALEN); - memset(hdr->addr3, 0xff, ETH_ALEN); + skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX); + + tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl)); + memset(tmpl, 0, sizeof(tmpl)); /* llc layer */ - memcpy(tmpl.llc_hdr, rfc1042_header, sizeof(rfc1042_header)); - tmpl.llc_type = cpu_to_be16(ETH_P_ARP); + memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header)); + tmpl->llc_type = cpu_to_be16(ETH_P_ARP); /* arp header */ - arp_hdr = &tmpl.arp_hdr; + arp_hdr = &tmpl->arp_hdr; arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER); arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP); arp_hdr->ar_hln = ETH_ALEN; @@ -1232,13 +1264,59 @@ int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif, arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY); /* arp payload */ - memcpy(tmpl.sender_hw, vif->addr, ETH_ALEN); - tmpl.sender_ip = ip_addr; + memcpy(tmpl->sender_hw, vif->addr, ETH_ALEN); + tmpl->sender_ip = wlvif->ip_addr; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, - &tmpl, sizeof(tmpl), 0, - wlvif->basic_rate); + /* encryption space */ + switch (wlvif->encryption_type) { + case KEY_TKIP: + extra = WL1271_EXTRA_SPACE_TKIP; + break; + case KEY_AES: + extra = WL1271_EXTRA_SPACE_AES; + break; + case KEY_NONE: + case KEY_WEP: + case KEY_GEM: + extra = 0; + break; + default: + wl1271_warning("Unknown encryption type: %d", + wlvif->encryption_type); + ret = -EINVAL; + goto out; + } + + if (extra) { + u8 *space = skb_push(skb, extra); + memset(space, 0, extra); + } + + /* QoS header - BE */ + if (wlvif->sta.qos) + memset(skb_push(skb, sizeof(__le16)), 0, sizeof(__le16)); + /* mac80211 header */ + hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr)); + memset(hdr, 0, sizeof(hdr)); + fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS; + if (wlvif->sta.qos) + fc |= IEEE80211_STYPE_QOS_DATA; + else + fc |= IEEE80211_STYPE_DATA; + if (wlvif->encryption_type != KEY_NONE) + fc |= IEEE80211_FCTL_PROTECTED; + + hdr->frame_control = cpu_to_le16(fc); + memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN); + memcpy(hdr->addr2, vif->addr, ETH_ALEN); + memset(hdr->addr3, 0xff, ETH_ALEN); + + ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP, + skb->data, skb->len, 0, + wlvif->basic_rate); +out: + dev_kfree_skb(skb); return ret; } @@ -1260,7 +1338,8 @@ int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif) /* FIXME: not sure what priority to use here */ template.qos_ctrl = cpu_to_le16(0); - return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, + return wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_QOS_NULL_DATA, &template, sizeof(template), 0, wlvif->basic_rate); } @@ -1739,11 +1818,20 @@ int wl12xx_croc(struct wl1271 *wl, u8 role_id) goto out; __clear_bit(role_id, wl->roc_map); + + /* + * Rearm the tx watchdog when removing the last ROC. This prevents + * recoveries due to just finished ROCs - when Tx hasn't yet had + * a chance to get out. + */ + if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) + wl12xx_rearm_tx_watchdog_locked(wl); out: return ret; } int wl12xx_cmd_channel_switch(struct wl1271 *wl, + struct wl12xx_vif *wlvif, struct ieee80211_channel_switch *ch_switch) { struct wl12xx_cmd_channel_switch *cmd; @@ -1757,10 +1845,13 @@ int wl12xx_cmd_channel_switch(struct wl1271 *wl, goto out; } + cmd->role_id = wlvif->role_id; cmd->channel = ch_switch->channel->hw_value; cmd->switch_time = ch_switch->count; - cmd->tx_suspend = ch_switch->block_tx; - cmd->flush = 0; /* this value is ignored by the FW */ + cmd->stop_tx = ch_switch->block_tx; + + /* FIXME: control from mac80211 in the future */ + cmd->post_switch_tx_disable = 0; /* Enable TX on the target channel */ ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 3f7d0b93c24..de217d92516 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h @@ -51,22 +51,23 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, - u8 ps_mode); + u8 ps_mode, u16 auto_ps_timeout); int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, size_t len); -int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, - void *buf, size_t buf_len, int index, u32 rates); +int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, + u16 template_id, void *buf, size_t buf_len, + int index, u32 rates); int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif); int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid); -int wl1271_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, +int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, + u8 role_id, u8 band, const u8 *ssid, size_t ssid_len, - const u8 *ie, size_t ie_len, u8 band); + const u8 *ie, size_t ie_len); struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct sk_buff *skb); -int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif, - __be32 ip_addr); +int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif); int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif); int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif); @@ -89,6 +90,7 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl); int wl12xx_cmd_start_fwlog(struct wl1271 *wl); int wl12xx_cmd_stop_fwlog(struct wl1271 *wl); int wl12xx_cmd_channel_switch(struct wl1271 *wl, + struct wl12xx_vif *wlvif, struct ieee80211_channel_switch *ch_switch); int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl); int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, @@ -96,62 +98,65 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid); enum wl1271_commands { - CMD_INTERROGATE = 1, /*use this to read information elements*/ - CMD_CONFIGURE = 2, /*use this to write information elements*/ - CMD_ENABLE_RX = 3, - CMD_ENABLE_TX = 4, - CMD_DISABLE_RX = 5, - CMD_DISABLE_TX = 6, - CMD_SCAN = 8, - CMD_STOP_SCAN = 9, - CMD_SET_KEYS = 12, - CMD_READ_MEMORY = 13, - CMD_WRITE_MEMORY = 14, - CMD_SET_TEMPLATE = 19, - CMD_TEST = 23, - CMD_NOISE_HIST = 28, - CMD_QUIET_ELEMENT_SET_STATE = 29, - CMD_SET_BCN_MODE = 33, - CMD_MEASUREMENT = 34, - CMD_STOP_MEASUREMENT = 35, - CMD_SET_PS_MODE = 37, - CMD_CHANNEL_SWITCH = 38, - CMD_STOP_CHANNEL_SWICTH = 39, - CMD_AP_DISCOVERY = 40, - CMD_STOP_AP_DISCOVERY = 41, - CMD_HEALTH_CHECK = 45, - CMD_DEBUG = 46, - CMD_TRIGGER_SCAN_TO = 47, - CMD_CONNECTION_SCAN_CFG = 48, - CMD_CONNECTION_SCAN_SSID_CFG = 49, - CMD_START_PERIODIC_SCAN = 50, - CMD_STOP_PERIODIC_SCAN = 51, - CMD_SET_PEER_STATE = 52, - CMD_REMAIN_ON_CHANNEL = 53, - CMD_CANCEL_REMAIN_ON_CHANNEL = 54, - - CMD_CONFIG_FWLOGGER = 55, - CMD_START_FWLOGGER = 56, - CMD_STOP_FWLOGGER = 57, - - /* AP commands */ - CMD_ADD_PEER = 62, - CMD_REMOVE_PEER = 63, + CMD_INTERROGATE = 1, /* use this to read information elements */ + CMD_CONFIGURE = 2, /* use this to write information elements */ + CMD_ENABLE_RX = 3, + CMD_ENABLE_TX = 4, + CMD_DISABLE_RX = 5, + CMD_DISABLE_TX = 6, + CMD_SCAN = 7, + CMD_STOP_SCAN = 8, + CMD_SET_KEYS = 9, + CMD_READ_MEMORY = 10, + CMD_WRITE_MEMORY = 11, + CMD_SET_TEMPLATE = 12, + CMD_TEST = 13, + CMD_NOISE_HIST = 14, + CMD_QUIET_ELEMENT_SET_STATE = 15, + CMD_SET_BCN_MODE = 16, + + CMD_MEASUREMENT = 17, + CMD_STOP_MEASUREMENT = 18, + CMD_SET_PS_MODE = 19, + CMD_CHANNEL_SWITCH = 20, + CMD_STOP_CHANNEL_SWICTH = 21, + CMD_AP_DISCOVERY = 22, + CMD_STOP_AP_DISCOVERY = 23, + CMD_HEALTH_CHECK = 24, + CMD_DEBUG = 25, + CMD_TRIGGER_SCAN_TO = 26, + CMD_CONNECTION_SCAN_CFG = 27, + CMD_CONNECTION_SCAN_SSID_CFG = 28, + CMD_START_PERIODIC_SCAN = 29, + CMD_STOP_PERIODIC_SCAN = 30, + CMD_SET_PEER_STATE = 31, + CMD_REMAIN_ON_CHANNEL = 32, + CMD_CANCEL_REMAIN_ON_CHANNEL = 33, + CMD_CONFIG_FWLOGGER = 34, + CMD_START_FWLOGGER = 35, + CMD_STOP_FWLOGGER = 36, + + /* Access point commands */ + CMD_ADD_PEER = 37, + CMD_REMOVE_PEER = 38, /* Role API */ - CMD_ROLE_ENABLE = 70, - CMD_ROLE_DISABLE = 71, - CMD_ROLE_START = 72, - CMD_ROLE_STOP = 73, + CMD_ROLE_ENABLE = 39, + CMD_ROLE_DISABLE = 40, + CMD_ROLE_START = 41, + CMD_ROLE_STOP = 42, - /* WIFI Direct */ - CMD_WFD_START_DISCOVERY = 80, - CMD_WFD_STOP_DISCOVERY = 81, - CMD_WFD_ATTRIBUTE_CONFIG = 82, + /* DFS */ + CMD_START_RADAR_DETECTION = 43, + CMD_STOP_RADAR_DETECTION = 44, - CMD_NOP = 100, + /* WIFI Direct */ + CMD_WFD_START_DISCOVERY = 45, + CMD_WFD_STOP_DISCOVERY = 46, + CMD_WFD_ATTRIBUTE_CONFIG = 47, + CMD_NOP = 48, + CMD_LAST_COMMAND, - NUM_COMMANDS, MAX_COMMAND_ID = 0xFFFF, }; @@ -191,7 +196,7 @@ enum cmd_templ { /* unit ms */ #define WL1271_COMMAND_TIMEOUT 2000 #define WL1271_CMD_TEMPL_DFLT_SIZE 252 -#define WL1271_CMD_TEMPL_MAX_SIZE 548 +#define WL1271_CMD_TEMPL_MAX_SIZE 512 #define WL1271_EVENT_TIMEOUT 750 struct wl1271_cmd_header { @@ -339,7 +344,9 @@ struct wl12xx_cmd_role_start { u8 ssid_len; u8 ssid[IEEE80211_MAX_SSID_LEN]; - u8 padding_1[5]; + u8 reset_tsf; + + u8 padding_1[4]; } __packed ap; }; } __packed; @@ -364,14 +371,18 @@ struct cmd_enabledisable_path { struct wl1271_cmd_template_set { struct wl1271_cmd_header header; - __le16 len; + u8 role_id; u8 template_type; + __le16 len; u8 index; /* relevant only for KLV_TEMPLATE type */ + u8 padding[3]; + __le32 enabled_rates; u8 short_retry_limit; u8 long_retry_limit; u8 aflags; u8 reserved; + u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE]; } __packed; @@ -388,6 +399,7 @@ struct wl1271_tim { } __packed; enum wl1271_cmd_ps_mode { + STATION_AUTO_PS_MODE, /* Dynamic Power Save */ STATION_ACTIVE_MODE, STATION_POWER_SAVE_MODE }; @@ -397,7 +409,7 @@ struct wl1271_cmd_ps_params { u8 role_id; u8 ps_mode; /* STATION_* */ - u8 padding[2]; + u16 auto_ps_timeout; } __packed; /* HW encryption keys */ @@ -695,14 +707,18 @@ struct wl12xx_cmd_stop_fwlog { struct wl12xx_cmd_channel_switch { struct wl1271_cmd_header header; + u8 role_id; + /* The new serving channel */ u8 channel; /* Relative time of the serving channel switch in TBTT units */ u8 switch_time; - /* 1: Suspend TX till switch time; 0: Do not suspend TX */ - u8 tx_suspend; - /* 1: Flush TX at switch time; 0: Do not flush */ - u8 flush; + /* Stop the role TX, should expect it after radar detection */ + u8 stop_tx; + /* The target channel tx status 1-stopped 0-open*/ + u8 post_switch_tx_disable; + + u8 padding[3]; } __packed; struct wl12xx_cmd_stop_channel_switch { diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index 1bcfb017058..3e581e19424 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h @@ -66,7 +66,8 @@ enum { }; enum { - CONF_HW_RXTX_RATE_MCS7 = 0, + CONF_HW_RXTX_RATE_MCS7_SGI = 0, + CONF_HW_RXTX_RATE_MCS7, CONF_HW_RXTX_RATE_MCS6, CONF_HW_RXTX_RATE_MCS5, CONF_HW_RXTX_RATE_MCS4, @@ -91,6 +92,10 @@ enum { CONF_HW_RXTX_RATE_UNSUPPORTED = 0xff }; +/* Rates between and including these are MCS rates */ +#define CONF_HW_RXTX_RATE_MCS_MIN CONF_HW_RXTX_RATE_MCS7_SGI +#define CONF_HW_RXTX_RATE_MCS_MAX CONF_HW_RXTX_RATE_MCS0 + enum { CONF_SG_DISABLE = 0, CONF_SG_PROTECTIVE, @@ -312,6 +317,10 @@ enum { CONF_AP_BT_ACL_VAL_BT_SERVE_TIME, CONF_AP_BT_ACL_VAL_WL_SERVE_TIME, + /* CTS Diluting params */ + CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH, + CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER, + CONF_SG_TEMP_PARAM_1, CONF_SG_TEMP_PARAM_2, CONF_SG_TEMP_PARAM_3, @@ -681,6 +690,9 @@ struct conf_tx_settings { */ u8 tmpl_short_retry_limit; u8 tmpl_long_retry_limit; + + /* Time in ms for Tx watchdog timer to expire */ + u32 tx_watchdog_timeout; }; enum { @@ -810,6 +822,19 @@ struct conf_conn_settings { u8 listen_interval; /* + * Firmware wakeup conditions during suspend + * Range: CONF_WAKE_UP_EVENT_* + */ + u8 suspend_wake_up_event; + + /* + * Listen interval during suspend. + * Currently will be in DTIMs (1-10) + * + */ + u8 suspend_listen_interval; + + /* * Enable or disable the beacon filtering. * * Range: CONF_BCN_FILT_MODE_* @@ -868,13 +893,6 @@ struct conf_conn_settings { u8 ps_poll_threshold; /* - * PS Poll failure recovery ACTIVE period length - * - * Range: u32 (ms) - */ - u32 ps_poll_recovery_period; - - /* * Configuration of signal average weights. */ struct conf_sig_weights sig_weights; @@ -922,6 +940,18 @@ struct conf_conn_settings { u8 psm_entry_nullfunc_retries; /* + * Specifies the dynamic PS timeout in ms that will be used + * by the FW when in AUTO_PS mode + */ + u16 dynamic_ps_timeout; + + /* + * Specifies whether dynamic PS should be disabled and PSM forced. + * This is required for certain WiFi certification tests. + */ + u8 forced_ps; + + /* * * Specifies the interval of the connection keep-alive null-func * frame in ms. @@ -1055,6 +1085,14 @@ struct conf_scan_settings { */ u16 num_probe_reqs; + /* + * Scan trigger (split scan) timeout. The FW will split the scan + * operation into slices of the given time and allow the FW to schedule + * other tasks in between. + * + * Range: u32 Microsecs + */ + u32 split_scan_timeout; }; struct conf_sched_scan_settings { diff --git a/drivers/net/wireless/wl12xx/debug.h b/drivers/net/wireless/wl12xx/debug.h index b85fd8c41e8..ec0fdc25b28 100644 --- a/drivers/net/wireless/wl12xx/debug.h +++ b/drivers/net/wireless/wl12xx/debug.h @@ -51,6 +51,7 @@ enum { DEBUG_FILTERS = BIT(15), DEBUG_ADHOC = BIT(16), DEBUG_AP = BIT(17), + DEBUG_PROBE = BIT(18), DEBUG_MASTER = (DEBUG_ADHOC | DEBUG_AP), DEBUG_ALL = ~0, }; diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index 15eb3a9c30c..e1cf7276596 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c @@ -113,7 +113,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) if (ret < 0) goto out; - if (wl->state == WL1271_STATE_ON && + if (wl->state == WL1271_STATE_ON && !wl->plt && time_after(jiffies, wl->stats.fw_stats_update + msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { wl1271_acx_statistics(wl, wl->stats.fw_stats); @@ -312,6 +312,181 @@ static const struct file_operations start_recovery_ops = { .llseek = default_llseek, }; +static ssize_t dynamic_ps_timeout_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + + return wl1271_format_buffer(user_buf, count, + ppos, "%d\n", + wl->conf.conn.dynamic_ps_timeout); +} + +static ssize_t dynamic_ps_timeout_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + struct wl12xx_vif *wlvif; + unsigned long value; + int ret; + + ret = kstrtoul_from_user(user_buf, count, 10, &value); + if (ret < 0) { + wl1271_warning("illegal value in dynamic_ps"); + return -EINVAL; + } + + if (value < 1 || value > 65535) { + wl1271_warning("dyanmic_ps_timeout is not in valid range"); + return -ERANGE; + } + + mutex_lock(&wl->mutex); + + wl->conf.conn.dynamic_ps_timeout = value; + + if (wl->state == WL1271_STATE_OFF) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + /* In case we're already in PSM, trigger it again to set new timeout + * immediately without waiting for re-association + */ + + wl12xx_for_each_wlvif_sta(wl, wlvif) { + if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) + wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE); + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations dynamic_ps_timeout_ops = { + .read = dynamic_ps_timeout_read, + .write = dynamic_ps_timeout_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + +static ssize_t forced_ps_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + + return wl1271_format_buffer(user_buf, count, + ppos, "%d\n", + wl->conf.conn.forced_ps); +} + +static ssize_t forced_ps_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + struct wl12xx_vif *wlvif; + unsigned long value; + int ret, ps_mode; + + ret = kstrtoul_from_user(user_buf, count, 10, &value); + if (ret < 0) { + wl1271_warning("illegal value in forced_ps"); + return -EINVAL; + } + + if (value != 1 && value != 0) { + wl1271_warning("forced_ps should be either 0 or 1"); + return -ERANGE; + } + + mutex_lock(&wl->mutex); + + if (wl->conf.conn.forced_ps == value) + goto out; + + wl->conf.conn.forced_ps = value; + + if (wl->state == WL1271_STATE_OFF) + goto out; + + ret = wl1271_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + /* In case we're already in PSM, trigger it again to switch mode + * immediately without waiting for re-association + */ + + ps_mode = value ? STATION_POWER_SAVE_MODE : STATION_AUTO_PS_MODE; + + wl12xx_for_each_wlvif_sta(wl, wlvif) { + if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) + wl1271_ps_set_mode(wl, wlvif, ps_mode); + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations forced_ps_ops = { + .read = forced_ps_read, + .write = forced_ps_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + +static ssize_t split_scan_timeout_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + + return wl1271_format_buffer(user_buf, count, + ppos, "%d\n", + wl->conf.scan.split_scan_timeout / 1000); +} + +static ssize_t split_scan_timeout_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + unsigned long value; + int ret; + + ret = kstrtoul_from_user(user_buf, count, 10, &value); + if (ret < 0) { + wl1271_warning("illegal value in split_scan_timeout"); + return -EINVAL; + } + + if (value == 0) + wl1271_info("split scan will be disabled"); + + mutex_lock(&wl->mutex); + + wl->conf.scan.split_scan_timeout = value * 1000; + + mutex_unlock(&wl->mutex); + return count; +} + +static const struct file_operations split_scan_timeout_ops = { + .read = split_scan_timeout_read, + .write = split_scan_timeout_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + static ssize_t driver_state_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -446,6 +621,7 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf, VIF_STATE_PRINT_INT(sta.basic_rate_idx); VIF_STATE_PRINT_INT(sta.ap_rate_idx); VIF_STATE_PRINT_INT(sta.p2p_rate_idx); + VIF_STATE_PRINT_INT(sta.qos); } else { VIF_STATE_PRINT_INT(ap.global_hlid); VIF_STATE_PRINT_INT(ap.bcast_hlid); @@ -471,7 +647,6 @@ static ssize_t vifs_state_read(struct file *file, char __user *user_buf, VIF_STATE_PRINT_INT(default_key); VIF_STATE_PRINT_INT(aid); VIF_STATE_PRINT_INT(session_counter); - VIF_STATE_PRINT_INT(ps_poll_failures); VIF_STATE_PRINT_INT(psm_entry_retry); VIF_STATE_PRINT_INT(power_level); VIF_STATE_PRINT_INT(rssi_thold); @@ -562,6 +737,64 @@ static const struct file_operations dtim_interval_ops = { .llseek = default_llseek, }; + + +static ssize_t suspend_dtim_interval_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + u8 value; + + if (wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_DTIM || + wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM) + value = wl->conf.conn.suspend_listen_interval; + else + value = 0; + + return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value); +} + +static ssize_t suspend_dtim_interval_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct wl1271 *wl = file->private_data; + unsigned long value; + int ret; + + ret = kstrtoul_from_user(user_buf, count, 10, &value); + if (ret < 0) { + wl1271_warning("illegal value for suspend_dtim_interval"); + return -EINVAL; + } + + if (value < 1 || value > 10) { + wl1271_warning("suspend_dtim value is not in valid range"); + return -ERANGE; + } + + mutex_lock(&wl->mutex); + + wl->conf.conn.suspend_listen_interval = value; + /* for some reason there are different event types for 1 and >1 */ + if (value == 1) + wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_DTIM; + else + wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM; + + mutex_unlock(&wl->mutex); + return count; +} + + +static const struct file_operations suspend_dtim_interval_ops = { + .read = suspend_dtim_interval_read, + .write = suspend_dtim_interval_write, + .open = wl1271_open_file_generic, + .llseek = default_llseek, +}; + static ssize_t beacon_interval_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -886,8 +1119,12 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(driver_state, rootdir); DEBUGFS_ADD(vifs_state, rootdir); DEBUGFS_ADD(dtim_interval, rootdir); + DEBUGFS_ADD(suspend_dtim_interval, rootdir); DEBUGFS_ADD(beacon_interval, rootdir); DEBUGFS_ADD(beacon_filtering, rootdir); + DEBUGFS_ADD(dynamic_ps_timeout, rootdir); + DEBUGFS_ADD(forced_ps, rootdir); + DEBUGFS_ADD(split_scan_timeout, rootdir); streaming = debugfs_create_dir("rx_streaming", rootdir); if (!streaming || IS_ERR(streaming)) diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index d3280df68f5..c953717f38e 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c @@ -30,133 +30,6 @@ #include "scan.h" #include "wl12xx_80211.h" -void wl1271_pspoll_work(struct work_struct *work) -{ - struct ieee80211_vif *vif; - struct wl12xx_vif *wlvif; - struct delayed_work *dwork; - struct wl1271 *wl; - int ret; - - dwork = container_of(work, struct delayed_work, work); - wlvif = container_of(dwork, struct wl12xx_vif, pspoll_work); - vif = container_of((void *)wlvif, struct ieee80211_vif, drv_priv); - wl = wlvif->wl; - - wl1271_debug(DEBUG_EVENT, "pspoll work"); - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - if (!test_and_clear_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags)) - goto out; - - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - goto out; - - /* - * if we end up here, then we were in powersave when the pspoll - * delivery failure occurred, and no-one changed state since, so - * we should go back to powersave. - */ - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE, - wlvif->basic_rate, true); - - wl1271_ps_elp_sleep(wl); -out: - mutex_unlock(&wl->mutex); -}; - -static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl, - struct wl12xx_vif *wlvif) -{ - int delay = wl->conf.conn.ps_poll_recovery_period; - int ret; - - wlvif->ps_poll_failures++; - if (wlvif->ps_poll_failures == 1) - wl1271_info("AP with dysfunctional ps-poll, " - "trying to work around it."); - - /* force active mode receive data from the AP */ - if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) { - ret = wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE, - wlvif->basic_rate, true); - if (ret < 0) - return; - set_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags); - ieee80211_queue_delayed_work(wl->hw, &wlvif->pspoll_work, - msecs_to_jiffies(delay)); - } - - /* - * If already in active mode, lets we should be getting data from - * the AP right away. If we enter PSM too fast after this, and data - * remains on the AP, we will get another event like this, and we'll - * go into active once more. - */ -} - -static int wl1271_event_ps_report(struct wl1271 *wl, - struct wl12xx_vif *wlvif, - struct event_mailbox *mbox, - bool *beacon_loss) -{ - int ret = 0; - u32 total_retries = wl->conf.conn.psm_entry_retries; - - wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); - - switch (mbox->ps_status) { - case EVENT_ENTER_POWER_SAVE_FAIL: - wl1271_debug(DEBUG_PSM, "PSM entry failed"); - - if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) { - /* remain in active mode */ - wlvif->psm_entry_retry = 0; - break; - } - - if (wlvif->psm_entry_retry < total_retries) { - wlvif->psm_entry_retry++; - ret = wl1271_ps_set_mode(wl, wlvif, - STATION_POWER_SAVE_MODE, - wlvif->basic_rate, true); - } else { - wl1271_info("No ack to nullfunc from AP."); - wlvif->psm_entry_retry = 0; - *beacon_loss = true; - } - break; - case EVENT_ENTER_POWER_SAVE_SUCCESS: - wlvif->psm_entry_retry = 0; - - /* - * BET has only a minor effect in 5GHz and masks - * channel switch IEs, so we only enable BET on 2.4GHz - */ - if (wlvif->band == IEEE80211_BAND_2GHZ) - /* enable beacon early termination */ - ret = wl1271_acx_bet_enable(wl, wlvif, true); - - if (wlvif->ps_compl) { - complete(wlvif->ps_compl); - wlvif->ps_compl = NULL; - } - break; - default: - break; - } - - return ret; -} - static void wl1271_event_rssi_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct event_mailbox *mbox) @@ -205,21 +78,13 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif) static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl, u8 enable) { - struct ieee80211_vif *vif; struct wl12xx_vif *wlvif; if (enable) { - /* disable dynamic PS when requested by the firmware */ - wl12xx_for_each_wlvif_sta(wl, wlvif) { - vif = wl12xx_wlvif_to_vif(wlvif); - ieee80211_disable_dyn_ps(vif); - } set_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); } else { clear_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags); wl12xx_for_each_wlvif_sta(wl, wlvif) { - vif = wl12xx_wlvif_to_vif(wlvif); - ieee80211_enable_dyn_ps(vif); wl1271_recalc_rx_streaming(wl, wlvif); } } @@ -237,7 +102,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) { struct ieee80211_vif *vif; struct wl12xx_vif *wlvif; - int ret; u32 vector; bool beacon_loss = false; bool disconnect_sta = false; @@ -293,21 +157,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) beacon_loss = true; } - if (vector & PS_REPORT_EVENT_ID) { - wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT"); - wl12xx_for_each_wlvif_sta(wl, wlvif) { - ret = wl1271_event_ps_report(wl, wlvif, - mbox, &beacon_loss); - if (ret < 0) - return ret; - } - } - - if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID) - wl12xx_for_each_wlvif_sta(wl, wlvif) { - wl1271_event_pspoll_delivery_fail(wl, wlvif); - } - if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { /* TODO: check actual multi-role support */ wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); @@ -344,7 +193,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) /* TODO: configure only the relevant vif */ wl12xx_for_each_wlvif_sta(wl, wlvif) { - struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); bool success; if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, @@ -352,6 +200,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) continue; success = mbox->channel_switch_status ? false : true; + vif = wl12xx_wlvif_to_vif(wlvif); + ieee80211_chswitch_done(vif, success); } } diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index 1d878ba47bf..057d193d352 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h @@ -51,10 +51,10 @@ enum { SCAN_COMPLETE_EVENT_ID = BIT(10), WFD_DISCOVERY_COMPLETE_EVENT_ID = BIT(11), AP_DISCOVERY_COMPLETE_EVENT_ID = BIT(12), - PS_REPORT_EVENT_ID = BIT(13), + RESERVED1 = BIT(13), PSPOLL_DELIVERY_FAILURE_EVENT_ID = BIT(14), - DISCONNECT_EVENT_COMPLETE_ID = BIT(15), - /* BIT(16) is reserved */ + ROLE_STOP_COMPLETE_EVENT_ID = BIT(15), + RADAR_DETECTED_EVENT_ID = BIT(16), CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17), BSS_LOSE_EVENT_ID = BIT(18), REGAINED_BSS_EVENT_ID = BIT(19), @@ -94,9 +94,9 @@ struct event_mailbox { u8 soft_gemini_sense_info; u8 soft_gemini_protective_info; s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS]; - u8 channel_switch_status; + u8 change_auto_mode_timeout; u8 scheduled_scan_status; - u8 ps_status; + u8 reserved4; /* tuned channel (roc) */ u8 roc_channel; @@ -119,17 +119,21 @@ struct event_mailbox { u8 rx_ba_allowed; u8 reserved_6[2]; + /* Channel switch results */ + + u8 channel_switch_role_id; + u8 channel_switch_status; + u8 reserved_7[2]; + u8 ps_poll_delivery_failure_role_ids; u8 stopped_role_ids; u8 started_role_ids; - u8 change_auto_mode_timeout; - u8 reserved_7[12]; + u8 reserved_8[9]; } __packed; int wl1271_event_unmask(struct wl1271 *wl); void wl1271_event_mbox_config(struct wl1271 *wl); int wl1271_event_handle(struct wl1271 *wl, u8 mbox); -void wl1271_pspoll_work(struct work_struct *work); #endif diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index ca7ee59e450..203fbebf09e 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -37,54 +37,64 @@ int wl1271_init_templates_config(struct wl1271 *wl) { int ret, i; + size_t max_size; /* send empty templates for fw memory reservation */ - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, - WL1271_CMD_TEMPL_DFLT_SIZE, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, + WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_CFG_PROBE_REQ_5, + NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_NULL_DATA, NULL, sizeof(struct wl12xx_null_data_template), 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_PS_POLL, NULL, sizeof(struct wl12xx_ps_poll_template), 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_QOS_NULL_DATA, NULL, sizeof (struct ieee80211_qos_hdr), 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_PROBE_RESPONSE, NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_BEACON, NULL, WL1271_CMD_TEMPL_DFLT_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_ARP_RSP, NULL, - sizeof - (struct wl12xx_arp_rsp_template), + max_size = sizeof(struct wl12xx_arp_rsp_template) + + WL1271_EXTRA_SPACE_MAX; + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_ARP_RSP, NULL, + max_size, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; @@ -93,19 +103,22 @@ int wl1271_init_templates_config(struct wl1271 *wl) * Put very large empty placeholders for all templates. These * reserve memory for later. */ - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_PROBE_RESPONSE, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_AP_PROBE_RESPONSE, NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_AP_BEACON, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_AP_BEACON, NULL, WL1271_CMD_TEMPL_MAX_SIZE, 0, WL1271_RATE_AUTOMATIC); if (ret < 0) return ret; - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_DEAUTH_AP, NULL, sizeof (struct wl12xx_disconn_template), 0, WL1271_RATE_AUTOMATIC); @@ -113,7 +126,8 @@ int wl1271_init_templates_config(struct wl1271 *wl) return ret; for (i = 0; i < CMD_TEMPL_KLV_IDX_MAX; i++) { - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, NULL, + ret = wl1271_cmd_template_set(wl, WL12XX_INVALID_ROLE_ID, + CMD_TEMPL_KLV, NULL, sizeof(struct ieee80211_qos_hdr), i, WL1271_RATE_AUTOMATIC); if (ret < 0) @@ -140,7 +154,8 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl, IEEE80211_STYPE_DEAUTH); rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_DEAUTH_AP, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_DEAUTH_AP, tmpl, sizeof(*tmpl), 0, rate); out: @@ -172,7 +187,8 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl, memcpy(nullfunc->addr3, vif->addr, ETH_ALEN); rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, nullfunc, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_NULL_DATA, nullfunc, sizeof(*nullfunc), 0, rate); out: @@ -204,7 +220,8 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl, memcpy(qosnull->addr3, vif->addr, ETH_ALEN); rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, qosnull, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, + CMD_TEMPL_QOS_NULL_DATA, qosnull, sizeof(*qosnull), 0, rate); out: diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c index 079ad380e8f..c574a3b31e3 100644 --- a/drivers/net/wireless/wl12xx/io.c +++ b/drivers/net/wireless/wl12xx/io.c @@ -45,6 +45,65 @@ #define OCP_STATUS_REQ_FAILED 0x20000 #define OCP_STATUS_RESP_ERROR 0x30000 +struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN] = { + [PART_DOWN] = { + .mem = { + .start = 0x00000000, + .size = 0x000177c0 + }, + .reg = { + .start = REGISTERS_BASE, + .size = 0x00008800 + }, + .mem2 = { + .start = 0x00000000, + .size = 0x00000000 + }, + .mem3 = { + .start = 0x00000000, + .size = 0x00000000 + }, + }, + + [PART_WORK] = { + .mem = { + .start = 0x00040000, + .size = 0x00014fc0 + }, + .reg = { + .start = REGISTERS_BASE, + .size = 0x0000a000 + }, + .mem2 = { + .start = 0x003004f8, + .size = 0x00000004 + }, + .mem3 = { + .start = 0x00040404, + .size = 0x00000000 + }, + }, + + [PART_DRPW] = { + .mem = { + .start = 0x00040000, + .size = 0x00014fc0 + }, + .reg = { + .start = DRPW_BASE, + .size = 0x00006000 + }, + .mem2 = { + .start = 0x00000000, + .size = 0x00000000 + }, + .mem3 = { + .start = 0x00000000, + .size = 0x00000000 + } + } +}; + bool wl1271_set_block_size(struct wl1271 *wl) { if (wl->if_ops->set_block_size) { diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index d398cbcea98..4fb3dab8c3b 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h @@ -43,6 +43,8 @@ #define HW_ACCESS_PRAM_MAX_RANGE 0x3c000 +extern struct wl1271_partition_set wl12xx_part_table[PART_TABLE_LEN]; + struct wl1271; void wl1271_disable_interrupts(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index d5f55a149de..39002363611 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -1,3 +1,4 @@ + /* * This file is part of wl1271 * @@ -115,6 +116,9 @@ static struct conf_drv_settings default_conf = { [CONF_AP_CONNECTION_PROTECTION_TIME] = 0, [CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25, [CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25, + /* CTS Diluting params */ + [CONF_SG_CTS_DILUTED_BAD_RX_PACKETS_TH] = 0, + [CONF_SG_CTS_CHOP_IN_DUAL_ANT_SCO_MASTER] = 0, }, .state = CONF_SG_PROTECTIVE, }, @@ -213,10 +217,13 @@ static struct conf_drv_settings default_conf = { .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS, .tmpl_short_retry_limit = 10, .tmpl_long_retry_limit = 10, + .tx_watchdog_timeout = 5000, }, .conn = { .wake_up_event = CONF_WAKE_UP_EVENT_DTIM, .listen_interval = 1, + .suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM, + .suspend_listen_interval = 3, .bcn_filt_mode = CONF_BCN_FILT_MODE_ENABLED, .bcn_filt_ie_count = 2, .bcn_filt_ie = { @@ -235,12 +242,13 @@ static struct conf_drv_settings default_conf = { .broadcast_timeout = 20000, .rx_broadcast_in_ps = 1, .ps_poll_threshold = 10, - .ps_poll_recovery_period = 700, .bet_enable = CONF_BET_MODE_ENABLE, .bet_max_consecutive = 50, .psm_entry_retries = 8, .psm_exit_retries = 16, .psm_entry_nullfunc_retries = 3, + .dynamic_ps_timeout = 200, + .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, }, @@ -265,6 +273,7 @@ static struct conf_drv_settings default_conf = { .min_dwell_time_passive = 100000, .max_dwell_time_passive = 100000, .num_probe_reqs = 2, + .split_scan_timeout = 50000, }, .sched_scan = { /* sched_scan requires dwell times in TU instead of TU/1000 */ @@ -384,15 +393,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, static void wl1271_op_stop(struct ieee80211_hw *hw); static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif); -static DEFINE_MUTEX(wl_list_mutex); -static LIST_HEAD(wl_list); - -static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, - unsigned char operstate) +static int wl12xx_set_authorized(struct wl1271 *wl, + struct wl12xx_vif *wlvif) { int ret; - if (operstate != IF_OPER_UP) + if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) + return -EINVAL; + + if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) return 0; if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags)) @@ -407,76 +416,6 @@ static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_info("Association completed."); return 0; } -static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, - void *arg) -{ - struct net_device *dev = arg; - struct wireless_dev *wdev; - struct wiphy *wiphy; - struct ieee80211_hw *hw; - struct wl1271 *wl; - struct wl1271 *wl_temp; - struct wl12xx_vif *wlvif; - int ret = 0; - - /* Check that this notification is for us. */ - if (what != NETDEV_CHANGE) - return NOTIFY_DONE; - - wdev = dev->ieee80211_ptr; - if (wdev == NULL) - return NOTIFY_DONE; - - wiphy = wdev->wiphy; - if (wiphy == NULL) - return NOTIFY_DONE; - - hw = wiphy_priv(wiphy); - if (hw == NULL) - return NOTIFY_DONE; - - wl_temp = hw->priv; - mutex_lock(&wl_list_mutex); - list_for_each_entry(wl, &wl_list, list) { - if (wl == wl_temp) - break; - } - mutex_unlock(&wl_list_mutex); - if (wl != wl_temp) - return NOTIFY_DONE; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) - goto out; - - if (dev->operstate != IF_OPER_UP) - goto out; - /* - * The correct behavior should be just getting the appropriate wlvif - * from the given dev, but currently we don't have a mac80211 - * interface for it. - */ - wl12xx_for_each_wlvif_sta(wl, wlvif) { - struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); - - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; - - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - wl1271_check_operstate(wl, wlvif, - ieee80211_get_operstate(vif)); - - wl1271_ps_elp_sleep(wl); - } -out: - mutex_unlock(&wl->mutex); - - return NOTIFY_OK; -} static int wl1271_reg_notify(struct wiphy *wiphy, struct regulatory_request *request) @@ -615,6 +554,80 @@ static void wl1271_rx_streaming_timer(unsigned long data) ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); } +/* wl->mutex must be taken */ +void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl) +{ + /* if the watchdog is not armed, don't do anything */ + if (wl->tx_allocated_blocks == 0) + return; + + cancel_delayed_work(&wl->tx_watchdog_work); + ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work, + msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout)); +} + +static void wl12xx_tx_watchdog_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, tx_watchdog_work); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + + /* Tx went out in the meantime - everything is ok */ + if (unlikely(wl->tx_allocated_blocks == 0)) + goto out; + + /* + * if a ROC is in progress, we might not have any Tx for a long + * time (e.g. pending Tx on the non-ROC channels) + */ + if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { + wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC", + wl->conf.tx.tx_watchdog_timeout); + wl12xx_rearm_tx_watchdog_locked(wl); + goto out; + } + + /* + * if a scan is in progress, we might not have any Tx for a long + * time + */ + if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { + wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan", + wl->conf.tx.tx_watchdog_timeout); + wl12xx_rearm_tx_watchdog_locked(wl); + goto out; + } + + /* + * AP might cache a frame for a long time for a sleeping station, + * so rearm the timer if there's an AP interface with stations. If + * Tx is genuinely stuck we will most hopefully discover it when all + * stations are removed due to inactivity. + */ + if (wl->active_sta_count) { + wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has " + " %d stations", + wl->conf.tx.tx_watchdog_timeout, + wl->active_sta_count); + wl12xx_rearm_tx_watchdog_locked(wl); + goto out; + } + + wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery", + wl->conf.tx.tx_watchdog_timeout); + wl12xx_queue_recovery_work(wl); + +out: + mutex_unlock(&wl->mutex); +} + static void wl1271_conf_init(struct wl1271 *wl) { @@ -672,8 +685,6 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) return ret; } - if (ret < 0) - return ret; /* Chip-specific initializations */ ret = wl1271_chip_specific_init(wl); @@ -809,6 +820,18 @@ static void wl12xx_fw_status(struct wl1271 *wl, wl->tx_allocated_blocks -= freed_blocks; + /* + * If the FW freed some blocks: + * If we still have allocated blocks - re-arm the timer, Tx is + * not stuck. Otherwise, cancel the timer (no Tx currently). + */ + if (freed_blocks) { + if (wl->tx_allocated_blocks) + wl12xx_rearm_tx_watchdog_locked(wl); + else + cancel_delayed_work(&wl->tx_watchdog_work); + } + avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks; /* @@ -985,16 +1008,70 @@ out: return IRQ_HANDLED; } -static int wl1271_fetch_firmware(struct wl1271 *wl) +struct vif_counter_data { + u8 counter; + + struct ieee80211_vif *cur_vif; + bool cur_vif_running; +}; + +static void wl12xx_vif_count_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct vif_counter_data *counter = data; + + counter->counter++; + if (counter->cur_vif == vif) + counter->cur_vif_running = true; +} + +/* caller must not hold wl->mutex, as it might deadlock */ +static void wl12xx_get_vif_count(struct ieee80211_hw *hw, + struct ieee80211_vif *cur_vif, + struct vif_counter_data *data) +{ + memset(data, 0, sizeof(*data)); + data->cur_vif = cur_vif; + + ieee80211_iterate_active_interfaces(hw, + wl12xx_vif_count_iter, data); +} + +static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt) { const struct firmware *fw; const char *fw_name; + enum wl12xx_fw_type fw_type; int ret; - if (wl->chip.id == CHIP_ID_1283_PG20) - fw_name = WL128X_FW_NAME; - else - fw_name = WL127X_FW_NAME; + if (plt) { + fw_type = WL12XX_FW_TYPE_PLT; + if (wl->chip.id == CHIP_ID_1283_PG20) + fw_name = WL128X_PLT_FW_NAME; + else + fw_name = WL127X_PLT_FW_NAME; + } else { + /* + * we can't call wl12xx_get_vif_count() here because + * wl->mutex is taken, so use the cached last_vif_count value + */ + if (wl->last_vif_count > 1) { + fw_type = WL12XX_FW_TYPE_MULTI; + if (wl->chip.id == CHIP_ID_1283_PG20) + fw_name = WL128X_FW_NAME_MULTI; + else + fw_name = WL127X_FW_NAME_MULTI; + } else { + fw_type = WL12XX_FW_TYPE_NORMAL; + if (wl->chip.id == CHIP_ID_1283_PG20) + fw_name = WL128X_FW_NAME_SINGLE; + else + fw_name = WL127X_FW_NAME_SINGLE; + } + } + + if (wl->fw_type == fw_type) + return 0; wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name); @@ -1013,6 +1090,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl) } vfree(wl->fw); + wl->fw_type = WL12XX_FW_TYPE_NONE; wl->fw_len = fw->size; wl->fw = vmalloc(wl->fw_len); @@ -1024,7 +1102,7 @@ static int wl1271_fetch_firmware(struct wl1271 *wl) memcpy(wl->fw, fw->data, wl->fw_len); ret = 0; - + wl->fw_type = fw_type; out: release_firmware(fw); @@ -1152,7 +1230,7 @@ static void wl1271_recovery_work(struct work_struct *work) mutex_lock(&wl->mutex); - if (wl->state != WL1271_STATE_ON) + if (wl->state != WL1271_STATE_ON || wl->plt) goto out_unlock; /* Avoid a recursive recovery */ @@ -1163,7 +1241,8 @@ static void wl1271_recovery_work(struct work_struct *work) wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); - BUG_ON(bug_on_recovery); + BUG_ON(bug_on_recovery && + !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); /* * Advance security sequence number to overcome potential progress @@ -1232,10 +1311,9 @@ static int wl1271_setup(struct wl1271 *wl) return 0; } -static int wl1271_chip_wakeup(struct wl1271 *wl) +static int wl12xx_set_power_on(struct wl1271 *wl) { - struct wl1271_partition_set partition; - int ret = 0; + int ret; msleep(WL1271_PRE_POWER_ON_SLEEP); ret = wl1271_power_on(wl); @@ -1245,20 +1323,22 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) wl1271_io_reset(wl); wl1271_io_init(wl); - /* We don't need a real memory partition here, because we only want - * to use the registers at this point. */ - memset(&partition, 0, sizeof(partition)); - partition.reg.start = REGISTERS_BASE; - partition.reg.size = REGISTERS_DOWN_SIZE; - wl1271_set_partition(wl, &partition); + wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]); /* ELP module wake up */ wl1271_fw_wakeup(wl); - /* whal_FwCtrl_BootSm() */ +out: + return ret; +} + +static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) +{ + int ret = 0; - /* 0. read chip id from CHIP_ID */ - wl->chip.id = wl1271_read32(wl, CHIP_ID_B); + ret = wl12xx_set_power_on(wl); + if (ret < 0) + goto out; /* * For wl127x based devices we could use the default block @@ -1307,11 +1387,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) goto out; } - if (wl->fw == NULL) { - ret = wl1271_fetch_firmware(wl); - if (ret < 0) - goto out; - } + ret = wl12xx_fetch_firmware(wl, plt); + if (ret < 0) + goto out; /* No NVS from netlink, try to get it from the filesystem */ if (wl->nvs == NULL) { @@ -1343,7 +1421,7 @@ int wl1271_plt_start(struct wl1271 *wl) while (retries) { retries--; - ret = wl1271_chip_wakeup(wl); + ret = wl12xx_chip_wakeup(wl, true); if (ret < 0) goto power_off; @@ -1355,7 +1433,8 @@ int wl1271_plt_start(struct wl1271 *wl) if (ret < 0) goto irq_disable; - wl->state = WL1271_STATE_PLT; + wl->plt = true; + wl->state = WL1271_STATE_ON; wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver_str); @@ -1391,41 +1470,52 @@ out: return ret; } -static int __wl1271_plt_stop(struct wl1271 *wl) +int wl1271_plt_stop(struct wl1271 *wl) { int ret = 0; wl1271_notice("power down"); - if (wl->state != WL1271_STATE_PLT) { + /* + * Interrupts must be disabled before setting the state to OFF. + * Otherwise, the interrupt handler might be called and exit without + * reading the interrupt status. + */ + wl1271_disable_interrupts(wl); + mutex_lock(&wl->mutex); + if (!wl->plt) { + mutex_unlock(&wl->mutex); + + /* + * This will not necessarily enable interrupts as interrupts + * may have been disabled when op_stop was called. It will, + * however, balance the above call to disable_interrupts(). + */ + wl1271_enable_interrupts(wl); + wl1271_error("cannot power down because not in PLT " "state: %d", wl->state); ret = -EBUSY; goto out; } - wl1271_power_off(wl); - - wl->state = WL1271_STATE_OFF; - wl->rx_counter = 0; - mutex_unlock(&wl->mutex); - wl1271_disable_interrupts(wl); + wl1271_flush_deferred_work(wl); cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->recovery_work); - mutex_lock(&wl->mutex); -out: - return ret; -} - -int wl1271_plt_stop(struct wl1271 *wl) -{ - int ret; + cancel_delayed_work_sync(&wl->elp_work); + cancel_delayed_work_sync(&wl->tx_watchdog_work); mutex_lock(&wl->mutex); - ret = __wl1271_plt_stop(wl); + wl1271_power_off(wl); + wl->flags = 0; + wl->state = WL1271_STATE_OFF; + wl->plt = false; + wl->rx_counter = 0; mutex_unlock(&wl->mutex); + +out: return ret; } @@ -1457,7 +1547,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) goto out; } - wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); + wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d", + hlid, q, skb->len); skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); wl->tx_queue_count[q]++; @@ -1555,10 +1646,6 @@ static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl) } -static struct notifier_block wl1271_dev_notifier = { - .notifier_call = wl1271_dev_notify, -}; - #ifdef CONFIG_PM static int wl1271_configure_suspend_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) @@ -1574,38 +1661,16 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, if (ret < 0) goto out_unlock; - /* enter psm if needed*/ - if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) { - DECLARE_COMPLETION_ONSTACK(compl); - - wlvif->ps_compl = &compl; - ret = wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE, - wlvif->basic_rate, true); - if (ret < 0) - goto out_sleep; - - /* we must unlock here so we will be able to get events */ - wl1271_ps_elp_sleep(wl); - mutex_unlock(&wl->mutex); + ret = wl1271_acx_wake_up_conditions(wl, wlvif, + wl->conf.conn.suspend_wake_up_event, + wl->conf.conn.suspend_listen_interval); - ret = wait_for_completion_timeout( - &compl, msecs_to_jiffies(WL1271_PS_COMPLETE_TIMEOUT)); + if (ret < 0) + wl1271_error("suspend: set wake up conditions failed: %d", ret); - mutex_lock(&wl->mutex); - if (ret <= 0) { - wl1271_warning("couldn't enter ps mode!"); - ret = -EBUSY; - goto out_cleanup; - } - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out_cleanup; - } -out_sleep: wl1271_ps_elp_sleep(wl); -out_cleanup: - wlvif->ps_compl = NULL; + out_unlock: mutex_unlock(&wl->mutex); return ret; @@ -1648,11 +1713,11 @@ static int wl1271_configure_suspend(struct wl1271 *wl, static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif) { - int ret; - bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; + int ret = 0; bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; + bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; - if (!is_sta && !is_ap) + if ((!is_ap) && (!is_sta)) return; mutex_lock(&wl->mutex); @@ -1661,12 +1726,16 @@ static void wl1271_configure_resume(struct wl1271 *wl, goto out; if (is_sta) { - /* exit psm if it wasn't configured */ - if (!test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) - wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE, - wlvif->basic_rate, true); + ret = wl1271_acx_wake_up_conditions(wl, wlvif, + wl->conf.conn.wake_up_event, + wl->conf.conn.listen_interval); + + if (ret < 0) + wl1271_error("resume: wake up conditions failed: %d", + ret); + } else if (is_ap) { - wl1271_acx_beacon_filter_opt(wl, wlvif, false); + ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); } wl1271_ps_elp_sleep(wl); @@ -1684,6 +1753,8 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); WARN_ON(!wow || !wow->any); + wl1271_tx_flush(wl); + wl->wow_enabled = true; wl12xx_for_each_wlvif(wl, wlvif) { ret = wl1271_configure_suspend(wl, wlvif); @@ -1709,9 +1780,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, wl1271_enable_interrupts(wl); flush_work(&wl->tx_work); - wl12xx_for_each_wlvif(wl, wlvif) { - flush_delayed_work(&wlvif->pspoll_work); - } flush_delayed_work(&wl->elp_work); return 0; @@ -1778,11 +1846,25 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl1271_debug(DEBUG_MAC80211, "mac80211 stop"); + /* + * Interrupts must be disabled before setting the state to OFF. + * Otherwise, the interrupt handler might be called and exit without + * reading the interrupt status. + */ + wl1271_disable_interrupts(wl); mutex_lock(&wl->mutex); if (wl->state == WL1271_STATE_OFF) { mutex_unlock(&wl->mutex); + + /* + * This will not necessarily enable interrupts as interrupts + * may have been disabled when op_stop was called. It will, + * however, balance the above call to disable_interrupts(). + */ + wl1271_enable_interrupts(wl); return; } + /* * this must be before the cancel_work calls below, so that the work * functions don't perform further work. @@ -1790,16 +1872,12 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl->state = WL1271_STATE_OFF; mutex_unlock(&wl->mutex); - mutex_lock(&wl_list_mutex); - list_del(&wl->list); - mutex_unlock(&wl_list_mutex); - - wl1271_disable_interrupts(wl); wl1271_flush_deferred_work(wl); cancel_delayed_work_sync(&wl->scan_complete_work); cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->elp_work); + cancel_delayed_work_sync(&wl->tx_watchdog_work); /* let's notify MAC80211 about the remaining pending TX frames */ wl12xx_tx_reset(wl, true); @@ -1969,7 +2047,6 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) wl1271_rx_streaming_enable_work); INIT_WORK(&wlvif->rx_streaming_disable_work, wl1271_rx_streaming_disable_work); - INIT_DELAYED_WORK(&wlvif->pspoll_work, wl1271_pspoll_work); INIT_LIST_HEAD(&wlvif->list); setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer, @@ -1986,7 +2063,7 @@ static bool wl12xx_init_fw(struct wl1271 *wl) while (retries) { retries--; - ret = wl1271_chip_wakeup(wl); + ret = wl12xx_chip_wakeup(wl, false); if (ret < 0) goto power_off; @@ -2051,30 +2128,77 @@ static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif) return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID; } +/* + * Check whether a fw switch (i.e. moving from one loaded + * fw to another) is needed. This function is also responsible + * for updating wl->last_vif_count, so it must be called before + * loading a non-plt fw (so the correct fw (single-role/multi-role) + * will be used). + */ +static bool wl12xx_need_fw_change(struct wl1271 *wl, + struct vif_counter_data vif_counter_data, + bool add) +{ + enum wl12xx_fw_type current_fw = wl->fw_type; + u8 vif_count = vif_counter_data.counter; + + if (test_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags)) + return false; + + /* increase the vif count if this is a new vif */ + if (add && !vif_counter_data.cur_vif_running) + vif_count++; + + wl->last_vif_count = vif_count; + + /* no need for fw change if the device is OFF */ + if (wl->state == WL1271_STATE_OFF) + return false; + + if (vif_count > 1 && current_fw == WL12XX_FW_TYPE_NORMAL) + return true; + if (vif_count <= 1 && current_fw == WL12XX_FW_TYPE_MULTI) + return true; + + return false; +} + +/* + * Enter "forced psm". Make sure the sta is in psm against the ap, + * to make the fw switch a bit more disconnection-persistent. + */ +static void wl12xx_force_active_psm(struct wl1271 *wl) +{ + struct wl12xx_vif *wlvif; + + wl12xx_for_each_wlvif_sta(wl, wlvif) { + wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE); + } +} + static int wl1271_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); + struct vif_counter_data vif_count; int ret = 0; u8 role_type; bool booted = false; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", ieee80211_vif_type_p2p(vif), vif->addr); + wl12xx_get_vif_count(hw, vif, &vif_count); + mutex_lock(&wl->mutex); ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out_unlock; - if (wl->vif) { - wl1271_debug(DEBUG_MAC80211, - "multiple vifs are not supported yet"); - ret = -EBUSY; - goto out; - } - /* * in some very corner case HW recovery scenarios its possible to * get here before __wl1271_op_remove_interface is complete, so @@ -2086,6 +2210,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, goto out; } + ret = wl12xx_init_vif_data(wl, vif); if (ret < 0) goto out; @@ -2097,6 +2222,14 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, goto out; } + if (wl12xx_need_fw_change(wl, vif_count, true)) { + wl12xx_force_active_psm(wl); + set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); + mutex_unlock(&wl->mutex); + wl1271_recovery_work(&wl->recovery_work); + return 0; + } + /* * TODO: after the nvs issue will be solved, move this block * to start(), and make sure here the driver is ON. @@ -2106,7 +2239,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, * we still need this in order to configure the fw * while uploading the nvs */ - memcpy(wl->mac_addr, vif->addr, ETH_ALEN); + memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN); booted = wl12xx_init_fw(wl); if (!booted) { @@ -2139,7 +2272,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, if (ret < 0) goto out; - wl->vif = vif; list_add(&wlvif->list, &wl->wlvif_list); set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags); @@ -2152,11 +2284,6 @@ out: out_unlock: mutex_unlock(&wl->mutex); - mutex_lock(&wl_list_mutex); - if (!ret) - list_add(&wl->list, &wl_list); - mutex_unlock(&wl_list_mutex); - return ret; } @@ -2172,20 +2299,20 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, if (!test_and_clear_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) return; - wl->vif = NULL; - /* because of hardware recovery, we may get here twice */ if (wl->state != WL1271_STATE_ON) return; wl1271_info("down"); - /* enable dyn ps just in case (if left on due to fw crash etc) */ - if (wlvif->bss_type == BSS_TYPE_STA_BSS) - ieee80211_enable_dyn_ps(vif); - if (wl->scan.state != WL1271_SCAN_STATE_IDLE && wl->scan_vif == vif) { + /* + * Rearm the tx watchdog just before idling scan. This + * prevents just-finished scans from triggering the watchdog + */ + wl12xx_rearm_tx_watchdog_locked(wl); + wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan_vif = NULL; @@ -2250,10 +2377,10 @@ deinit: wl->sta_count--; mutex_unlock(&wl->mutex); + del_timer_sync(&wlvif->rx_streaming_timer); cancel_work_sync(&wlvif->rx_streaming_enable_work); cancel_work_sync(&wlvif->rx_streaming_disable_work); - cancel_delayed_work_sync(&wlvif->pspoll_work); mutex_lock(&wl->mutex); } @@ -2264,7 +2391,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl12xx_vif *iter; + struct vif_counter_data vif_count; + bool cancel_recovery = true; + wl12xx_get_vif_count(hw, vif, &vif_count); mutex_lock(&wl->mutex); if (wl->state == WL1271_STATE_OFF || @@ -2283,20 +2413,34 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, break; } WARN_ON(iter != wlvif); + if (wl12xx_need_fw_change(wl, vif_count, false)) { + wl12xx_force_active_psm(wl); + set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags); + wl12xx_queue_recovery_work(wl); + cancel_recovery = false; + } out: mutex_unlock(&wl->mutex); - cancel_work_sync(&wl->recovery_work); + if (cancel_recovery) + cancel_work_sync(&wl->recovery_work); } static int wl12xx_op_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype new_type, bool p2p) { + struct wl1271 *wl = hw->priv; + int ret; + + set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); wl1271_op_remove_interface(hw, vif); - vif->type = ieee80211_iftype_p2p(new_type, p2p); + vif->type = new_type; vif->p2p = p2p; - return wl1271_op_add_interface(hw, vif); + ret = wl1271_op_add_interface(hw, vif); + + clear_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags); + return ret; } static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, @@ -2317,6 +2461,9 @@ static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) wl1271_info("JOIN while associated."); + /* clear encryption type */ + wlvif->encryption_type = KEY_NONE; + if (set_assoc) set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags); @@ -2467,71 +2614,61 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_warning("rate policy for channel " "failed %d", ret); - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, - &wlvif->flags)) { - if (wl12xx_dev_role_started(wlvif)) { - /* roaming */ - ret = wl12xx_croc(wl, - wlvif->dev_role_id); - if (ret < 0) - return ret; - } - ret = wl1271_join(wl, wlvif, false); + /* + * change the ROC channel. do it only if we are + * not idle. otherwise, CROC will be called + * anyway. + */ + if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, + &wlvif->flags) && + wl12xx_dev_role_started(wlvif) && + !(conf->flags & IEEE80211_CONF_IDLE)) { + ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) - wl1271_warning("cmd join on channel " - "failed %d", ret); - } else { - /* - * change the ROC channel. do it only if we are - * not idle. otherwise, CROC will be called - * anyway. - */ - if (wl12xx_dev_role_started(wlvif) && - !(conf->flags & IEEE80211_CONF_IDLE)) { - ret = wl12xx_stop_dev(wl, wlvif); - if (ret < 0) - return ret; + return ret; - ret = wl12xx_start_dev(wl, wlvif); - if (ret < 0) - return ret; - } + ret = wl12xx_start_dev(wl, wlvif); + if (ret < 0) + return ret; } } } - /* - * if mac80211 changes the PSM mode, make sure the mode is not - * incorrectly changed after the pspoll failure active window. - */ - if (changed & IEEE80211_CONF_CHANGE_PS) - clear_bit(WLVIF_FLAG_PSPOLL_FAILURE, &wlvif->flags); + if ((changed & IEEE80211_CONF_CHANGE_PS) && !is_ap) { - if (conf->flags & IEEE80211_CONF_PS && - !test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) { - set_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags); + if ((conf->flags & IEEE80211_CONF_PS) && + test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && + !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) { - /* - * We enter PSM only if we're already associated. - * If we're not, we'll enter it when joining an SSID, - * through the bss_info_changed() hook. - */ - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { - wl1271_debug(DEBUG_PSM, "psm enabled"); - ret = wl1271_ps_set_mode(wl, wlvif, - STATION_POWER_SAVE_MODE, - wlvif->basic_rate, true); - } - } else if (!(conf->flags & IEEE80211_CONF_PS) && - test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags)) { - wl1271_debug(DEBUG_PSM, "psm disabled"); + int ps_mode; + char *ps_mode_str; + + if (wl->conf.conn.forced_ps) { + ps_mode = STATION_POWER_SAVE_MODE; + ps_mode_str = "forced"; + } else { + ps_mode = STATION_AUTO_PS_MODE; + ps_mode_str = "auto"; + } + + wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str); + + ret = wl1271_ps_set_mode(wl, wlvif, ps_mode); - clear_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags); + if (ret < 0) + wl1271_warning("enter %s ps failed %d", + ps_mode_str, ret); + + } else if (!(conf->flags & IEEE80211_CONF_PS) && + test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) { + + wl1271_debug(DEBUG_PSM, "auto ps disabled"); - if (test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) ret = wl1271_ps_set_mode(wl, wlvif, - STATION_ACTIVE_MODE, - wlvif->basic_rate, true); + STATION_ACTIVE_MODE); + if (ret < 0) + wl1271_warning("exit auto ps failed %d", ret); + } } if (conf->power_level != wlvif->power_level) { @@ -2971,6 +3108,21 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wl1271_error("Could not add or replace key"); goto out_sleep; } + + /* + * reconfiguring arp response if the unicast (or common) + * encryption key type was changed + */ + if (wlvif->bss_type == BSS_TYPE_STA_BSS && + (sta || key_type == KEY_WEP) && + wlvif->encryption_type != key_type) { + wlvif->encryption_type = key_type; + ret = wl1271_cmd_build_arp_rsp(wl, wlvif); + if (ret < 0) { + wl1271_warning("build arp rsp failed: %d", ret); + goto out_sleep; + } + } break; case DISABLE_KEY: @@ -3004,8 +3156,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req) { struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); - int ret; u8 *ssid = NULL; size_t len = 0; @@ -3033,17 +3183,13 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out; - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && - test_bit(wlvif->role_id, wl->roc_map)) { + /* fail if there is any role in ROC */ + if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { /* don't allow scanning right now */ ret = -EBUSY; goto out_sleep; } - /* cancel ROC before scanning */ - if (wl12xx_dev_role_started(wlvif)) - wl12xx_stop_dev(wl, wlvif); - ret = wl1271_scan(hw->priv, vif, ssid, len, req); out_sleep: wl1271_ps_elp_sleep(wl); @@ -3078,6 +3224,13 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out_sleep; } + + /* + * Rearm the tx watchdog just before idling scan. This + * prevents just-finished scans from triggering the watchdog + */ + wl12xx_rearm_tx_watchdog_locked(wl); + wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan_vif = NULL; @@ -3105,6 +3258,11 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); + if (wl->state == WL1271_STATE_OFF) { + ret = -EAGAIN; + goto out; + } + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -3136,6 +3294,9 @@ static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); + if (wl->state == WL1271_STATE_OFF) + goto out; + ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; @@ -3263,6 +3424,7 @@ static void wl12xx_remove_vendor_ie(struct sk_buff *skb, static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates, struct ieee80211_vif *vif) { + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct sk_buff *skb; int ret; @@ -3270,7 +3432,7 @@ static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates, if (!skb) return -EOPNOTSUPP; - ret = wl1271_cmd_template_set(wl, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_AP_PROBE_RESPONSE, skb->data, skb->len, 0, @@ -3294,7 +3456,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl, /* no need to change probe response if the SSID is set correctly */ if (wlvif->ssid_len > 0) - return wl1271_cmd_template_set(wl, + return wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_AP_PROBE_RESPONSE, probe_rsp_data, probe_rsp_len, 0, @@ -3331,7 +3493,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl, ptr, probe_rsp_len - (ptr - probe_rsp_data)); templ_len += probe_rsp_len - (ptr - probe_rsp_data); - return wl1271_cmd_template_set(wl, + return wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_AP_PROBE_RESPONSE, probe_rsp_templ, templ_len, 0, @@ -3428,7 +3590,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON : CMD_TEMPL_BEACON; - ret = wl1271_cmd_template_set(wl, tmpl_id, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id, beacon->data, beacon->len, 0, min_rate); @@ -3467,7 +3629,7 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl, beacon->len, min_rate); else - ret = wl1271_cmd_template_set(wl, + ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_PROBE_RESPONSE, beacon->data, beacon->len, 0, @@ -3592,10 +3754,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, ibss_joined = true; } else { if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, - &wlvif->flags)) { + &wlvif->flags)) wl1271_unjoin(wl, wlvif); - wl12xx_start_dev(wl, wlvif); - } } } @@ -3613,7 +3773,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, do_join = true; } - if (changed & BSS_CHANGED_IDLE) { + if (changed & BSS_CHANGED_IDLE && !is_ibss) { ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); if (ret < 0) wl1271_warning("idle mode change failed %d", ret); @@ -3631,7 +3791,8 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, wlvif->rssi_thold = bss_conf->cqm_rssi_thold; } - if (changed & BSS_CHANGED_BSSID) + if (changed & BSS_CHANGED_BSSID && + (is_ibss || bss_conf->assoc)) if (!is_zero_ether_addr(bss_conf->bssid)) { ret = wl12xx_cmd_build_null_data(wl, wlvif); if (ret < 0) @@ -3668,10 +3829,9 @@ sta_not_found: u32 rates; int ieoffset; wlvif->aid = bss_conf->aid; + wlvif->beacon_int = bss_conf->beacon_int; set_assoc = true; - wlvif->ps_poll_failures = 0; - /* * use basic rates from AP, and determine lowest rate * to use with control frames. @@ -3731,9 +3891,6 @@ sta_not_found: dev_kfree_skb(wlvif->probereq); wlvif->probereq = NULL; - /* re-enable dynamic ps - just in case */ - ieee80211_enable_dyn_ps(vif); - /* revert back to minimum rates for the current band */ wl1271_set_band_rate(wl, wlvif); wlvif->basic_rate = @@ -3753,7 +3910,6 @@ sta_not_found: /* restore the bssid filter and go to dummy bssid */ if (was_assoc) { - u32 conf_flags = wl->hw->conf.flags; /* * we might have to disable roc, if there was * no IF_OPER_UP notification. @@ -3776,7 +3932,7 @@ sta_not_found: } wl1271_unjoin(wl, wlvif); - if (!(conf_flags & IEEE80211_CONF_IDLE)) + if (!bss_conf->idle) wl12xx_start_dev(wl, wlvif); } } @@ -3807,34 +3963,6 @@ sta_not_found: if (ret < 0) goto out; - if (changed & BSS_CHANGED_ARP_FILTER) { - __be32 addr = bss_conf->arp_addr_list[0]; - WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS); - - if (bss_conf->arp_addr_cnt == 1 && - bss_conf->arp_filter_enabled) { - /* - * The template should have been configured only upon - * association. however, it seems that the correct ip - * isn't being set (when sending), so we have to - * reconfigure the template upon every ip change. - */ - ret = wl1271_cmd_build_arp_rsp(wl, wlvif, addr); - if (ret < 0) { - wl1271_warning("build arp rsp failed: %d", ret); - goto out; - } - - ret = wl1271_acx_arp_ip_filter(wl, wlvif, - ACX_ARP_FILTER_ARP_FILTERING, - addr); - } else - ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr); - - if (ret < 0) - goto out; - } - if (do_join) { ret = wl1271_join(wl, wlvif, set_assoc); if (ret < 0) { @@ -3848,8 +3976,8 @@ sta_not_found: if (ret < 0) goto out; - wl1271_check_operstate(wl, wlvif, - ieee80211_get_operstate(vif)); + if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) + wl12xx_set_authorized(wl, wlvif); } /* * stop device role if started (we might already be in @@ -3860,19 +3988,6 @@ sta_not_found: if (ret < 0) goto out; } - - /* If we want to go in PSM but we're not there yet */ - if (test_bit(WLVIF_FLAG_PSM_REQUESTED, &wlvif->flags) && - !test_bit(WLVIF_FLAG_PSM, &wlvif->flags)) { - enum wl1271_cmd_ps_mode mode; - - mode = STATION_POWER_SAVE_MODE; - ret = wl1271_ps_set_mode(wl, wlvif, mode, - wlvif->basic_rate, - true); - if (ret < 0) - goto out; - } } /* Handle new association with HT. Do this after join. */ @@ -3914,6 +4029,41 @@ sta_not_found: } } + /* Handle arp filtering. Done after join. */ + if ((changed & BSS_CHANGED_ARP_FILTER) || + (!is_ibss && (changed & BSS_CHANGED_QOS))) { + __be32 addr = bss_conf->arp_addr_list[0]; + wlvif->sta.qos = bss_conf->qos; + WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS); + + if (bss_conf->arp_addr_cnt == 1 && + bss_conf->arp_filter_enabled) { + wlvif->ip_addr = addr; + /* + * The template should have been configured only upon + * association. however, it seems that the correct ip + * isn't being set (when sending), so we have to + * reconfigure the template upon every ip change. + */ + ret = wl1271_cmd_build_arp_rsp(wl, wlvif); + if (ret < 0) { + wl1271_warning("build arp rsp failed: %d", ret); + goto out; + } + + ret = wl1271_acx_arp_ip_filter(wl, wlvif, + (ACX_ARP_FILTER_ARP_FILTERING | + ACX_ARP_FILTER_AUTO_ARP), + addr); + } else { + wlvif->ip_addr = 0; + ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr); + } + + if (ret < 0) + goto out; + } + out: return; } @@ -4009,6 +4159,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw, { struct wl1271 *wl = hw->priv; + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); u64 mactime = ULLONG_MAX; int ret; @@ -4023,7 +4174,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw, if (ret < 0) goto out; - ret = wl1271_acx_tsf_info(wl, &mactime); + ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime); if (ret < 0) goto out_sleep; @@ -4085,107 +4236,155 @@ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid) clear_bit(hlid, wlvif->ap.sta_hlid_map); memset(wl->links[hlid].addr, 0, ETH_ALEN); wl->links[hlid].ba_bitmap = 0; - wl1271_tx_reset_link_queues(wl, hlid); __clear_bit(hlid, &wl->ap_ps_map); __clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map); wl12xx_free_link(wl, wlvif, &hlid); wl->active_sta_count--; + + /* + * rearm the tx watchdog when the last STA is freed - give the FW a + * chance to return STA-buffered packets before complaining. + */ + if (wl->active_sta_count == 0) + wl12xx_rearm_tx_watchdog_locked(wl); } -static int wl1271_op_sta_add(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static int wl12xx_sta_add(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta) { - struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl1271_station *wl_sta; int ret = 0; u8 hlid; - mutex_lock(&wl->mutex); - - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; - - if (wlvif->bss_type != BSS_TYPE_AP_BSS) - goto out; - wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid); ret = wl1271_allocate_sta(wl, wlvif, sta); if (ret < 0) - goto out; + return ret; wl_sta = (struct wl1271_station *)sta->drv_priv; hlid = wl_sta->hlid; - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out_free_sta; - ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid); if (ret < 0) - goto out_sleep; + wl1271_free_sta(wl, wlvif, hlid); - ret = wl12xx_cmd_set_peer_state(wl, hlid); - if (ret < 0) - goto out_sleep; + return ret; +} - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid); - if (ret < 0) - goto out_sleep; +static int wl12xx_sta_remove(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta) +{ + struct wl1271_station *wl_sta; + int ret = 0, id; -out_sleep: - wl1271_ps_elp_sleep(wl); + wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); + + wl_sta = (struct wl1271_station *)sta->drv_priv; + id = wl_sta->hlid; + if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) + return -EINVAL; -out_free_sta: + ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); if (ret < 0) - wl1271_free_sta(wl, wlvif, hlid); + return ret; -out: - mutex_unlock(&wl->mutex); + wl1271_free_sta(wl, wlvif, wl_sta->hlid); return ret; } -static int wl1271_op_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) +static int wl12xx_update_sta_state(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) { - struct wl1271 *wl = hw->priv; - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); struct wl1271_station *wl_sta; - int ret = 0, id; + u8 hlid; + bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS; + bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS; + int ret; - mutex_lock(&wl->mutex); + wl_sta = (struct wl1271_station *)sta->drv_priv; + hlid = wl_sta->hlid; - if (unlikely(wl->state == WL1271_STATE_OFF)) - goto out; + /* Add station (AP mode) */ + if (is_ap && + old_state == IEEE80211_STA_NOTEXIST && + new_state == IEEE80211_STA_NONE) + return wl12xx_sta_add(wl, wlvif, sta); + + /* Remove station (AP mode) */ + if (is_ap && + old_state == IEEE80211_STA_NONE && + new_state == IEEE80211_STA_NOTEXIST) { + /* must not fail */ + wl12xx_sta_remove(wl, wlvif, sta); + return 0; + } - if (wlvif->bss_type != BSS_TYPE_AP_BSS) - goto out; + /* Authorize station (AP mode) */ + if (is_ap && + new_state == IEEE80211_STA_AUTHORIZED) { + ret = wl12xx_cmd_set_peer_state(wl, hlid); + if (ret < 0) + return ret; - wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid); + ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, + hlid); + return ret; + } - wl_sta = (struct wl1271_station *)sta->drv_priv; - id = wl_sta->hlid; - if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map))) + /* Authorize station */ + if (is_sta && + new_state == IEEE80211_STA_AUTHORIZED) { + set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); + return wl12xx_set_authorized(wl, wlvif); + } + + if (is_sta && + old_state == IEEE80211_STA_AUTHORIZED && + new_state == IEEE80211_STA_ASSOC) { + clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags); + return 0; + } + + return 0; +} + +static int wl12xx_op_sta_state(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + enum ieee80211_sta_state old_state, + enum ieee80211_sta_state new_state) +{ + struct wl1271 *wl = hw->priv; + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); + int ret; + + wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d", + sta->aid, old_state, new_state); + + mutex_lock(&wl->mutex); + + if (unlikely(wl->state == WL1271_STATE_OFF)) { + ret = -EBUSY; goto out; + } ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) goto out; - ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid); - if (ret < 0) - goto out_sleep; + ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state); - wl1271_free_sta(wl, wlvif, wl_sta->hlid); - -out_sleep: wl1271_ps_elp_sleep(wl); - out: mutex_unlock(&wl->mutex); + if (new_state < old_state) + return 0; return ret; } @@ -4354,6 +4553,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); + wl1271_tx_flush(wl); + mutex_lock(&wl->mutex); if (unlikely(wl->state == WL1271_STATE_OFF)) { @@ -4370,7 +4571,7 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, /* TODO: change mac80211 to pass vif as param */ wl12xx_for_each_wlvif_sta(wl, wlvif) { - ret = wl12xx_cmd_channel_switch(wl, ch_switch); + ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch); if (!ret) set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags); @@ -4464,6 +4665,7 @@ static struct ieee80211_channel wl1271_channels[] = { /* mapping to indexes for wl1271_rates */ static const u8 wl1271_rate_to_idx_2ghz[] = { /* MCS rates are used only with 11n */ + 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */ 7, /* CONF_HW_RXTX_RATE_MCS7 */ 6, /* CONF_HW_RXTX_RATE_MCS6 */ 5, /* CONF_HW_RXTX_RATE_MCS5 */ @@ -4585,6 +4787,7 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = { /* mapping to indexes for wl1271_rates_5ghz */ static const u8 wl1271_rate_to_idx_5ghz[] = { /* MCS rates are used only with 11n */ + 7, /* CONF_HW_RXTX_RATE_MCS7_SGI */ 7, /* CONF_HW_RXTX_RATE_MCS7 */ 6, /* CONF_HW_RXTX_RATE_MCS6 */ 5, /* CONF_HW_RXTX_RATE_MCS5 */ @@ -4650,8 +4853,7 @@ static const struct ieee80211_ops wl1271_ops = { .conf_tx = wl1271_op_conf_tx, .get_tsf = wl1271_op_get_tsf, .get_survey = wl1271_op_get_survey, - .sta_add = wl1271_op_sta_add, - .sta_remove = wl1271_op_sta_remove, + .sta_state = wl12xx_op_sta_state, .ampdu_action = wl1271_op_ampdu_action, .tx_frames_pending = wl1271_tx_frames_pending, .set_bitrate_mask = wl12xx_set_bitrate_mask, @@ -4825,13 +5027,120 @@ static struct bin_attribute fwlog_attr = { .read = wl1271_sysfs_read_fwlog, }; +static bool wl12xx_mac_in_fuse(struct wl1271 *wl) +{ + bool supported = false; + u8 major, minor; + + if (wl->chip.id == CHIP_ID_1283_PG20) { + major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver); + minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver); + + /* in wl128x we have the MAC address if the PG is >= (2, 1) */ + if (major > 2 || (major == 2 && minor >= 1)) + supported = true; + } else { + major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver); + minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver); + + /* in wl127x we have the MAC address if the PG is >= (3, 1) */ + if (major == 3 && minor >= 1) + supported = true; + } + + wl1271_debug(DEBUG_PROBE, + "PG Ver major = %d minor = %d, MAC %s present", + major, minor, supported ? "is" : "is not"); + + return supported; +} + +static void wl12xx_derive_mac_addresses(struct wl1271 *wl, + u32 oui, u32 nic, int n) +{ + int i; + + wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x, n %d", + oui, nic, n); + + if (nic + n - 1 > 0xffffff) + wl1271_warning("NIC part of the MAC address wraps around!"); + + for (i = 0; i < n; i++) { + wl->addresses[i].addr[0] = (u8)(oui >> 16); + wl->addresses[i].addr[1] = (u8)(oui >> 8); + wl->addresses[i].addr[2] = (u8) oui; + wl->addresses[i].addr[3] = (u8)(nic >> 16); + wl->addresses[i].addr[4] = (u8)(nic >> 8); + wl->addresses[i].addr[5] = (u8) nic; + nic++; + } + + wl->hw->wiphy->n_addresses = n; + wl->hw->wiphy->addresses = wl->addresses; +} + +static void wl12xx_get_fuse_mac(struct wl1271 *wl) +{ + u32 mac1, mac2; + + wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]); + + mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1); + mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2); + + /* these are the two parts of the BD_ADDR */ + wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + + ((mac1 & 0xff000000) >> 24); + wl->fuse_nic_addr = mac1 & 0xffffff; + + wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]); +} + +static int wl12xx_get_hw_info(struct wl1271 *wl) +{ + int ret; + u32 die_info; + + ret = wl12xx_set_power_on(wl); + if (ret < 0) + goto out; + + wl->chip.id = wl1271_read32(wl, CHIP_ID_B); + + if (wl->chip.id == CHIP_ID_1283_PG20) + die_info = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1); + else + die_info = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1); + + wl->hw_pg_ver = (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET; + + if (!wl12xx_mac_in_fuse(wl)) { + wl->fuse_oui_addr = 0; + wl->fuse_nic_addr = 0; + } else { + wl12xx_get_fuse_mac(wl); + } + + wl1271_power_off(wl); +out: + return ret; +} + static int wl1271_register_hw(struct wl1271 *wl) { int ret; + u32 oui_addr = 0, nic_addr = 0; if (wl->mac80211_registered) return 0; + ret = wl12xx_get_hw_info(wl); + if (ret < 0) { + wl1271_error("couldn't get hw info"); + goto out; + } + ret = wl1271_fetch_nvs(wl); if (ret == 0) { /* NOTE: The wl->nvs->nvs element must be first, in @@ -4840,39 +5149,42 @@ static int wl1271_register_hw(struct wl1271 *wl) */ u8 *nvs_ptr = (u8 *)wl->nvs; - wl->mac_addr[0] = nvs_ptr[11]; - wl->mac_addr[1] = nvs_ptr[10]; - wl->mac_addr[2] = nvs_ptr[6]; - wl->mac_addr[3] = nvs_ptr[5]; - wl->mac_addr[4] = nvs_ptr[4]; - wl->mac_addr[5] = nvs_ptr[3]; + oui_addr = + (nvs_ptr[11] << 16) + (nvs_ptr[10] << 8) + nvs_ptr[6]; + nic_addr = + (nvs_ptr[5] << 16) + (nvs_ptr[4] << 8) + nvs_ptr[3]; } - SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); + /* if the MAC address is zeroed in the NVS derive from fuse */ + if (oui_addr == 0 && nic_addr == 0) { + oui_addr = wl->fuse_oui_addr; + /* fuse has the BD_ADDR, the WLAN addresses are the next two */ + nic_addr = wl->fuse_nic_addr + 1; + } + + wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr, 2); ret = ieee80211_register_hw(wl->hw); if (ret < 0) { wl1271_error("unable to register mac80211 hw: %d", ret); - return ret; + goto out; } wl->mac80211_registered = true; wl1271_debugfs_init(wl); - register_netdevice_notifier(&wl1271_dev_notifier); - wl1271_notice("loaded"); - return 0; +out: + return ret; } static void wl1271_unregister_hw(struct wl1271 *wl) { - if (wl->state == WL1271_STATE_PLT) - __wl1271_plt_stop(wl); + if (wl->plt) + wl1271_plt_stop(wl); - unregister_netdevice_notifier(&wl1271_dev_notifier); ieee80211_unregister_hw(wl->hw); wl->mac80211_registered = false; @@ -4889,7 +5201,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) }; /* The tx descriptor buffer and the TKIP space. */ - wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + + wl->hw->extra_tx_headroom = WL1271_EXTRA_SPACE_TKIP + sizeof(struct wl1271_tx_hw_descr); /* unit us */ @@ -4898,17 +5210,17 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS | IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_SUPPORTS_CQM_RSSI | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_AP_LINK_PS | IEEE80211_HW_AMPDU_AGGREGATION | - IEEE80211_HW_TX_AMPDU_SETUP_IN_HW; + IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | + IEEE80211_HW_SCAN_WHILE_IDLE; wl->hw->wiphy->cipher_suites = cipher_suites; wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); @@ -4924,10 +5236,10 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) * should be the maximum length possible for a template, without * the IEEE80211 header of the template */ - wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE - + wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - sizeof(struct ieee80211_header); - wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE - + wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE - sizeof(struct ieee80211_header); wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; @@ -4993,7 +5305,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) wl = hw->priv; memset(wl, 0, sizeof(*wl)); - INIT_LIST_HEAD(&wl->list); INIT_LIST_HEAD(&wl->wlvif_list); wl->hw = hw; @@ -5010,6 +5321,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) INIT_WORK(&wl->tx_work, wl1271_tx_work); INIT_WORK(&wl->recovery_work, wl1271_recovery_work); INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); + INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work); wl->freezable_wq = create_freezable_workqueue("wl12xx_wq"); if (!wl->freezable_wq) { @@ -5021,7 +5333,6 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) wl->rx_counter = 0; wl->power_level = WL1271_DEFAULT_POWER_LEVEL; wl->band = IEEE80211_BAND_2GHZ; - wl->vif = NULL; wl->flags = 0; wl->sg_enabled = true; wl->hw_pg_ver = -1; @@ -5046,6 +5357,7 @@ static struct ieee80211_hw *wl1271_alloc_hw(void) spin_lock_init(&wl->wl_lock); wl->state = WL1271_STATE_OFF; + wl->fw_type = WL12XX_FW_TYPE_NONE; mutex_init(&wl->mutex); /* Apply default driver configuration. */ @@ -5113,6 +5425,7 @@ static int wl1271_free_hw(struct wl1271 *wl) vfree(wl->fw); wl->fw = NULL; + wl->fw_type = WL12XX_FW_TYPE_NONE; kfree(wl->nvs); wl->nvs = NULL; @@ -5299,7 +5612,7 @@ module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(debug_level, "wl12xx debugging level"); module_param_named(fwlog, fwlog_param, charp, 0); -MODULE_PARM_DESC(keymap, +MODULE_PARM_DESC(fwlog, "FW logger options: continuous, ondemand, dbgpins or disable"); module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR); diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index a2bdacdd7e1..78f598b4f97 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c @@ -56,7 +56,7 @@ void wl1271_elp_work(struct work_struct *work) if (wlvif->bss_type == BSS_TYPE_AP_BSS) goto out; - if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && + if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) && test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) goto out; } @@ -69,8 +69,6 @@ out: mutex_unlock(&wl->mutex); } -#define ELP_ENTRY_DELAY 5 - /* Routines to toggle sleep mode while in ELP */ void wl1271_ps_elp_sleep(struct wl1271 *wl) { @@ -84,13 +82,13 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) if (wlvif->bss_type == BSS_TYPE_AP_BSS) return; - if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && + if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) && test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return; } ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, - msecs_to_jiffies(ELP_ENTRY_DELAY)); + msecs_to_jiffies(wl->conf.conn.dynamic_ps_timeout)); } int wl1271_ps_elp_wakeup(struct wl1271 *wl) @@ -160,28 +158,39 @@ out: } int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, - enum wl1271_cmd_ps_mode mode, u32 rates, bool send) + enum wl1271_cmd_ps_mode mode) { int ret; + u16 timeout = wl->conf.conn.dynamic_ps_timeout; switch (mode) { + case STATION_AUTO_PS_MODE: case STATION_POWER_SAVE_MODE: - wl1271_debug(DEBUG_PSM, "entering psm"); + wl1271_debug(DEBUG_PSM, "entering psm (mode=%d,timeout=%u)", + mode, timeout); - ret = wl1271_acx_wake_up_conditions(wl, wlvif); + ret = wl1271_acx_wake_up_conditions(wl, wlvif, + wl->conf.conn.wake_up_event, + wl->conf.conn.listen_interval); if (ret < 0) { wl1271_error("couldn't set wake up conditions"); return ret; } - ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_POWER_SAVE_MODE); + ret = wl1271_cmd_ps_mode(wl, wlvif, mode, timeout); if (ret < 0) return ret; - set_bit(WLVIF_FLAG_PSM, &wlvif->flags); + set_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); + + /* enable beacon early termination. Not relevant for 5GHz */ + if (wlvif->band == IEEE80211_BAND_2GHZ) { + ret = wl1271_acx_bet_enable(wl, wlvif, true); + if (ret < 0) + return ret; + } break; case STATION_ACTIVE_MODE: - default: wl1271_debug(DEBUG_PSM, "leaving psm"); /* disable beacon early termination */ @@ -191,12 +200,15 @@ int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, return ret; } - ret = wl1271_cmd_ps_mode(wl, wlvif, STATION_ACTIVE_MODE); + ret = wl1271_cmd_ps_mode(wl, wlvif, mode, 0); if (ret < 0) return ret; - clear_bit(WLVIF_FLAG_PSM, &wlvif->flags); + clear_bit(WLVIF_FLAG_IN_PS, &wlvif->flags); break; + default: + wl1271_warning("trying to set ps to unsupported mode %d", mode); + ret = -EINVAL; } return ret; diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h index a12052f0202..5f19d4fbbf2 100644 --- a/drivers/net/wireless/wl12xx/ps.h +++ b/drivers/net/wireless/wl12xx/ps.h @@ -28,7 +28,7 @@ #include "acx.h" int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, - enum wl1271_cmd_ps_mode mode, u32 rates, bool send); + enum wl1271_cmd_ps_mode mode); void wl1271_ps_elp_sleep(struct wl1271 *wl); int wl1271_ps_elp_wakeup(struct wl1271 *wl); void wl1271_elp_work(struct work_struct *work); diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h index df34d5977b9..340db324bc2 100644 --- a/drivers/net/wireless/wl12xx/reg.h +++ b/drivers/net/wireless/wl12xx/reg.h @@ -525,4 +525,31 @@ b12-b0 - Supported Rate indicator bits as defined below. */ #define INTR_TRIG_TX_PROC1 BIT(18) +#define WL127X_REG_FUSE_DATA_2_1 0x050a +#define WL128X_REG_FUSE_DATA_2_1 0x2152 +#define PG_VER_MASK 0x3c +#define PG_VER_OFFSET 2 + +#define WL127X_PG_MAJOR_VER_MASK 0x3 +#define WL127X_PG_MAJOR_VER_OFFSET 0x0 +#define WL127X_PG_MINOR_VER_MASK 0xc +#define WL127X_PG_MINOR_VER_OFFSET 0x2 + +#define WL128X_PG_MAJOR_VER_MASK 0xc +#define WL128X_PG_MAJOR_VER_OFFSET 0x2 +#define WL128X_PG_MINOR_VER_MASK 0x3 +#define WL128X_PG_MINOR_VER_OFFSET 0x0 + +#define WL127X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL127X_PG_MAJOR_VER_MASK) >> \ + WL127X_PG_MAJOR_VER_OFFSET) +#define WL127X_PG_GET_MINOR(pg_ver) ((pg_ver & WL127X_PG_MINOR_VER_MASK) >> \ + WL127X_PG_MINOR_VER_OFFSET) +#define WL128X_PG_GET_MAJOR(pg_ver) ((pg_ver & WL128X_PG_MAJOR_VER_MASK) >> \ + WL128X_PG_MAJOR_VER_OFFSET) +#define WL128X_PG_GET_MINOR(pg_ver) ((pg_ver & WL128X_PG_MINOR_VER_MASK) >> \ + WL128X_PG_MINOR_VER_OFFSET) + +#define WL12XX_REG_FUSE_BD_ADDR_1 0x00310eb4 +#define WL12XX_REG_FUSE_BD_ADDR_2 0x00310eb8 + #endif diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 4fbd2a722ff..cfa6071704c 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c @@ -113,7 +113,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, * In PLT mode we seem to get frames and mac80211 warns about them, * workaround this by not retrieving them at all. */ - if (unlikely(wl->state == WL1271_STATE_PLT)) + if (unlikely(wl->plt)) return -EINVAL; /* the data read starts with the descriptor */ diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index e24111ececc..fcba055ef19 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -38,7 +38,6 @@ void wl1271_scan_complete_work(struct work_struct *work) struct ieee80211_vif *vif; struct wl12xx_vif *wlvif; int ret; - bool is_sta, is_ibss; dwork = container_of(work, struct delayed_work, work); wl = container_of(dwork, struct wl1271, scan_complete_work); @@ -56,6 +55,12 @@ void wl1271_scan_complete_work(struct work_struct *work) vif = wl->scan_vif; wlvif = wl12xx_vif_to_data(vif); + /* + * Rearm the tx watchdog just before idling scan. This + * prevents just-finished scans from triggering the watchdog + */ + wl12xx_rearm_tx_watchdog_locked(wl); + wl->scan.state = WL1271_SCAN_STATE_IDLE; memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch)); wl->scan.req = NULL; @@ -70,15 +75,6 @@ void wl1271_scan_complete_work(struct work_struct *work) wl1271_cmd_build_ap_probe_req(wl, wlvif, wlvif->probereq); } - /* return to ROC if needed */ - is_sta = (wlvif->bss_type == BSS_TYPE_STA_BSS); - is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS); - if (((is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) || - (is_ibss && !test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))) && - !test_bit(wlvif->dev_role_id, wl->roc_map)) { - /* restore remain on channel */ - wl12xx_start_dev(wl, wlvif); - } wl1271_ps_elp_sleep(wl); if (wl->scan.failed) { @@ -182,14 +178,23 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif, goto out; } + if (wl->conf.scan.split_scan_timeout) + scan_options |= WL1271_SCAN_OPT_SPLIT_SCAN; + if (passive) scan_options |= WL1271_SCAN_OPT_PASSIVE; - if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID)) { + if (wlvif->bss_type == BSS_TYPE_AP_BSS || + test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) + cmd->params.role_id = wlvif->role_id; + else + cmd->params.role_id = wlvif->dev_role_id; + + if (WARN_ON(cmd->params.role_id == WL12XX_INVALID_ROLE_ID)) { ret = -EINVAL; goto out; } - cmd->params.role_id = wlvif->role_id; + cmd->params.scan_options = cpu_to_le16(scan_options); cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, @@ -202,7 +207,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif, cmd->params.tx_rate = cpu_to_le32(basic_rate); cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; - cmd->params.tid_trigger = 0; + cmd->params.tid_trigger = CONF_TX_AC_ANY_TID; cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; if (band == IEEE80211_BAND_2GHZ) @@ -217,16 +222,17 @@ static int wl1271_scan_send(struct wl1271 *wl, struct ieee80211_vif *vif, memcpy(cmd->addr, vif->addr, ETH_ALEN); - ret = wl1271_cmd_build_probe_req(wl, wlvif, wl->scan.ssid, - wl->scan.ssid_len, wl->scan.req->ie, - wl->scan.req->ie_len, band); + ret = wl12xx_cmd_build_probe_req(wl, wlvif, + cmd->params.role_id, band, + wl->scan.ssid, wl->scan.ssid_len, + wl->scan.req->ie, + wl->scan.req->ie_len); if (ret < 0) { wl1271_error("PROBE request template failed"); goto out; } - /* disable the timeout */ - trigger->timeout = 0; + trigger->timeout = cpu_to_le32(wl->conf.scan.split_scan_timeout); ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, sizeof(*trigger), 0); if (ret < 0) { @@ -658,11 +664,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, } if (!force_passive && cfg->active[0]) { - ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid, + u8 band = IEEE80211_BAND_2GHZ; + ret = wl12xx_cmd_build_probe_req(wl, wlvif, + wlvif->dev_role_id, band, + req->ssids[0].ssid, req->ssids[0].ssid_len, - ies->ie[IEEE80211_BAND_2GHZ], - ies->len[IEEE80211_BAND_2GHZ], - IEEE80211_BAND_2GHZ); + ies->ie[band], + ies->len[band]); if (ret < 0) { wl1271_error("2.4GHz PROBE request template failed"); goto out; @@ -670,11 +678,13 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, } if (!force_passive && cfg->active[1]) { - ret = wl1271_cmd_build_probe_req(wl, wlvif, req->ssids[0].ssid, + u8 band = IEEE80211_BAND_5GHZ; + ret = wl12xx_cmd_build_probe_req(wl, wlvif, + wlvif->dev_role_id, band, + req->ssids[0].ssid, req->ssids[0].ssid_len, - ies->ie[IEEE80211_BAND_5GHZ], - ies->len[IEEE80211_BAND_5GHZ], - IEEE80211_BAND_5GHZ); + ies->ie[band], + ies->len[band]); if (ret < 0) { wl1271_error("5GHz PROBE request template failed"); goto out; diff --git a/drivers/net/wireless/wl12xx/scan.h b/drivers/net/wireless/wl12xx/scan.h index a7ed43dc08c..96ff457a3a0 100644 --- a/drivers/net/wireless/wl12xx/scan.h +++ b/drivers/net/wireless/wl12xx/scan.h @@ -48,7 +48,7 @@ void wl1271_scan_sched_scan_results(struct wl1271 *wl); #define WL1271_SCAN_CURRENT_TX_PWR 0 #define WL1271_SCAN_OPT_ACTIVE 0 #define WL1271_SCAN_OPT_PASSIVE 1 -#define WL1271_SCAN_OPT_TRIGGERED_SCAN 2 +#define WL1271_SCAN_OPT_SPLIT_SCAN 2 #define WL1271_SCAN_OPT_PRIORITY_HIGH 4 /* scan even if we fail to enter psm */ #define WL1271_SCAN_OPT_FORCE 8 diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index 468a50553fa..4b3c32774ba 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -74,6 +74,8 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); struct sdio_func *func = dev_to_sdio_func(glue->dev); + sdio_claim_host(func); + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", @@ -88,6 +90,8 @@ static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, addr, len); } + sdio_release_host(func); + if (ret) dev_err(child->parent, "sdio read failed (%d)\n", ret); } @@ -99,6 +103,8 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); struct sdio_func *func = dev_to_sdio_func(glue->dev); + sdio_claim_host(func); + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); dev_dbg(child->parent, "sdio write 52 addr 0x%x, byte 0x%02x\n", @@ -113,6 +119,8 @@ static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, ret = sdio_memcpy_toio(func, addr, buf, len); } + sdio_release_host(func); + if (ret) dev_err(child->parent, "sdio write failed (%d)\n", ret); } @@ -136,6 +144,7 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) sdio_claim_host(func); sdio_enable_func(func); + sdio_release_host(func); out: return ret; @@ -146,6 +155,7 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); + sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); @@ -314,9 +324,6 @@ static int wl1271_suspend(struct device *dev) dev_err(dev, "error while trying to keep power\n"); goto out; } - - /* release host */ - sdio_release_host(func); } out: return ret; @@ -324,15 +331,7 @@ out: static int wl1271_resume(struct device *dev) { - struct sdio_func *func = dev_to_sdio_func(dev); - struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); - struct wl1271 *wl = platform_get_drvdata(glue->core); - dev_dbg(dev, "wl1271 resume\n"); - if (wl->wow_enabled) { - /* claim back host */ - sdio_claim_host(func); - } return 0; } @@ -371,5 +370,9 @@ module_exit(wl1271_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); -MODULE_FIRMWARE(WL127X_FW_NAME); -MODULE_FIRMWARE(WL128X_FW_NAME); +MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); +MODULE_FIRMWARE(WL127X_FW_NAME_MULTI); +MODULE_FIRMWARE(WL127X_PLT_FW_NAME); +MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE); +MODULE_FIRMWARE(WL128X_FW_NAME_MULTI); +MODULE_FIRMWARE(WL128X_PLT_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 92caa7ce605..2fc18a8dcce 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -433,6 +433,10 @@ module_exit(wl1271_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); -MODULE_FIRMWARE(WL127X_FW_NAME); -MODULE_FIRMWARE(WL128X_FW_NAME); +MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE); +MODULE_FIRMWARE(WL127X_FW_NAME_MULTI); +MODULE_FIRMWARE(WL127X_PLT_FW_NAME); +MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE); +MODULE_FIRMWARE(WL128X_FW_NAME_MULTI); +MODULE_FIRMWARE(WL128X_PLT_FW_NAME); MODULE_ALIAS("spi:wl1271"); diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c index 25093c0cb0e..1e93bb9c024 100644 --- a/drivers/net/wireless/wl12xx/testmode.c +++ b/drivers/net/wireless/wl12xx/testmode.c @@ -30,6 +30,7 @@ #include "acx.h" #include "reg.h" #include "ps.h" +#include "io.h" #define WL1271_TM_MAX_DATA_LENGTH 1024 @@ -41,6 +42,7 @@ enum wl1271_tm_commands { WL1271_TM_CMD_NVS_PUSH, /* Not in use. Keep to not break ABI */ WL1271_TM_CMD_SET_PLT_MODE, WL1271_TM_CMD_RECOVER, + WL1271_TM_CMD_GET_MAC, __WL1271_TM_CMD_AFTER_LAST }; @@ -264,6 +266,52 @@ static int wl1271_tm_cmd_recover(struct wl1271 *wl, struct nlattr *tb[]) return 0; } +static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[]) +{ + struct sk_buff *skb; + u8 mac_addr[ETH_ALEN]; + int ret = 0; + + mutex_lock(&wl->mutex); + + if (!wl->plt) { + ret = -EINVAL; + goto out; + } + + if (wl->fuse_oui_addr == 0 && wl->fuse_nic_addr == 0) { + ret = -EOPNOTSUPP; + goto out; + } + + mac_addr[0] = (u8)(wl->fuse_oui_addr >> 16); + mac_addr[1] = (u8)(wl->fuse_oui_addr >> 8); + mac_addr[2] = (u8) wl->fuse_oui_addr; + mac_addr[3] = (u8)(wl->fuse_nic_addr >> 16); + mac_addr[4] = (u8)(wl->fuse_nic_addr >> 8); + mac_addr[5] = (u8) wl->fuse_nic_addr; + + skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, ETH_ALEN); + if (!skb) { + ret = -ENOMEM; + goto out; + } + + NLA_PUT(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr); + ret = cfg80211_testmode_reply(skb); + if (ret < 0) + goto out; + +out: + mutex_unlock(&wl->mutex); + return ret; + +nla_put_failure: + kfree_skb(skb); + ret = -EMSGSIZE; + goto out; +} + int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) { struct wl1271 *wl = hw->priv; @@ -288,6 +336,8 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) return wl1271_tm_cmd_set_plt_mode(wl, tb); case WL1271_TM_CMD_RECOVER: return wl1271_tm_cmd_recover(wl, tb); + case WL1271_TM_CMD_GET_MAC: + return wl12xx_tm_cmd_get_mac(wl, tb); default: return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 4508ccd7832..43ae49143d6 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -77,35 +77,6 @@ static void wl1271_free_tx_id(struct wl1271 *wl, int id) } } -static int wl1271_tx_update_filters(struct wl1271 *wl, - struct wl12xx_vif *wlvif, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - int ret; - - hdr = (struct ieee80211_hdr *)skb->data; - - /* - * stop bssid-based filtering before transmitting authentication - * requests. this way the hw will never drop authentication - * responses coming from BSSIDs it isn't familiar with (e.g. on - * roaming) - */ - if (!ieee80211_is_auth(hdr->frame_control)) - return 0; - - if (wlvif->dev_hlid != WL12XX_INVALID_LINK_ID) - goto out; - - wl1271_debug(DEBUG_CMD, "starting device role for roaming"); - ret = wl12xx_start_dev(wl, wlvif); - if (ret < 0) - goto out; -out: - return 0; -} - static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, struct sk_buff *skb) { @@ -187,8 +158,6 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (wlvif->bss_type == BSS_TYPE_AP_BSS) return wl12xx_tx_get_hlid_ap(wl, wlvif, skb); - wl1271_tx_update_filters(wl, wlvif, skb); - if ((test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) || test_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags)) && !ieee80211_is_auth(hdr->frame_control) && @@ -257,6 +226,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl->tx_blocks_available -= total_blocks; wl->tx_allocated_blocks += total_blocks; + /* If the FW was empty before, arm the Tx watchdog */ + if (wl->tx_allocated_blocks == total_blocks) + wl12xx_rearm_tx_watchdog_locked(wl); + ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); wl->tx_allocated_pkts[ac]++; @@ -286,16 +259,20 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, int aligned_len, ac, rate_idx; s64 hosttime; u16 tx_attr = 0; + __le16 frame_control; + struct ieee80211_hdr *hdr; + u8 *frame_start; bool is_dummy; desc = (struct wl1271_tx_hw_descr *) skb->data; + frame_start = (u8 *)(desc + 1); + hdr = (struct ieee80211_hdr *)(frame_start + extra); + frame_control = hdr->frame_control; /* relocate space for security header */ if (extra) { - void *framestart = skb->data + sizeof(*desc); - u16 fc = *(u16 *)(framestart + extra); - int hdrlen = ieee80211_hdrlen(cpu_to_le16(fc)); - memmove(framestart, framestart + extra, hdrlen); + int hdrlen = ieee80211_hdrlen(frame_control); + memmove(frame_start, hdr, hdrlen); } /* configure packet life time */ @@ -384,6 +361,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, desc->wl127x_mem.total_mem_blocks); } + /* for WEP shared auth - no fw encryption is needed */ + if (ieee80211_is_auth(frame_control) && + ieee80211_has_protected(frame_control)) + tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; + desc->tx_attr = cpu_to_le16(tx_attr); } @@ -408,7 +390,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (info->control.hw_key && info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) - extra = WL1271_TKIP_IV_SPACE; + extra = WL1271_EXTRA_SPACE_TKIP; if (info->control.hw_key) { bool is_wep; @@ -549,6 +531,7 @@ static struct sk_buff *wl12xx_lnk_skb_dequeue(struct wl1271 *wl, if (skb) { int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); + WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -593,6 +576,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) struct wl12xx_vif *wlvif = wl->last_wlvif; struct sk_buff *skb = NULL; + /* continue from last wlvif (round robin) */ if (wlvif) { wl12xx_for_each_wlvif_continue(wl, wlvif) { skb = wl12xx_vif_skb_dequeue(wl, wlvif); @@ -603,7 +587,11 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) } } - /* do another pass */ + /* dequeue from the system HLID before the restarting wlvif list */ + if (!skb) + skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); + + /* do a new pass over the wlvif list */ if (!skb) { wl12xx_for_each_wlvif(wl, wlvif) { skb = wl12xx_vif_skb_dequeue(wl, wlvif); @@ -611,12 +599,16 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) wl->last_wlvif = wlvif; break; } + + /* + * No need to continue after last_wlvif. The previous + * pass should have found it. + */ + if (wlvif == wl->last_wlvif) + break; } } - if (!skb) - skb = wl12xx_lnk_skb_dequeue(wl, &wl->links[wl->system_hlid]); - if (!skb && test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) { int q; @@ -624,6 +616,7 @@ static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl) skb = wl->dummy_packet; q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); spin_lock_irqsave(&wl->wl_lock, flags); + WARN_ON_ONCE(wl->tx_queue_count[q] <= 0); wl->tx_queue_count[q]--; spin_unlock_irqrestore(&wl->wl_lock, flags); } @@ -795,6 +788,18 @@ out: mutex_unlock(&wl->mutex); } +static u8 wl1271_tx_get_rate_flags(u8 rate_class_index) +{ + u8 flags = 0; + + if (rate_class_index >= CONF_HW_RXTX_RATE_MCS_MIN && + rate_class_index <= CONF_HW_RXTX_RATE_MCS_MAX) + flags |= IEEE80211_TX_RC_MCS; + if (rate_class_index == CONF_HW_RXTX_RATE_MCS7_SGI) + flags |= IEEE80211_TX_RC_SHORT_GI; + return flags; +} + static void wl1271_tx_complete_packet(struct wl1271 *wl, struct wl1271_tx_hw_res_descr *result) { @@ -804,6 +809,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, struct sk_buff *skb; int id = result->id; int rate = -1; + u8 rate_flags = 0; u8 retries = 0; /* check for id legality */ @@ -830,6 +836,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, info->flags |= IEEE80211_TX_STAT_ACK; rate = wl1271_rate_to_idx(result->rate_class_index, wlvif->band); + rate_flags = wl1271_tx_get_rate_flags(result->rate_class_index); retries = result->ack_failures; } else if (result->status == TX_RETRY_EXCEEDED) { wl->stats.excessive_retries++; @@ -838,7 +845,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, info->status.rates[0].idx = rate; info->status.rates[0].count = retries; - info->status.rates[0].flags = 0; + info->status.rates[0].flags = rate_flags; info->status.ack_signal = -1; wl->stats.retry_count += result->ack_failures; @@ -869,8 +876,9 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, if (info->control.hw_key && info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); - memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen); - skb_pull(skb, WL1271_TKIP_IV_SPACE); + memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, + hdrlen); + skb_pull(skb, WL1271_EXTRA_SPACE_TKIP); } wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x" @@ -966,7 +974,6 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) else wlvif->sta.ba_rx_bitmap = 0; - wl1271_tx_reset_link_queues(wl, i); wl->links[i].allocated_pkts = 0; wl->links[i].prev_freed_pkts = 0; } @@ -980,8 +987,14 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) struct sk_buff *skb; struct ieee80211_tx_info *info; - for (i = 0; i < NUM_TX_QUEUES; i++) - wl->tx_queue_count[i] = 0; + /* only reset the queues if something bad happened */ + if (WARN_ON_ONCE(wl1271_tx_total_queue_count(wl) != 0)) { + for (i = 0; i < WL12XX_MAX_LINKS; i++) + wl1271_tx_reset_link_queues(wl, i); + + for (i = 0; i < NUM_TX_QUEUES; i++) + wl->tx_queue_count[i] = 0; + } wl->stopped_queues_map = 0; @@ -1012,9 +1025,9 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); - memmove(skb->data + WL1271_TKIP_IV_SPACE, + memmove(skb->data + WL1271_EXTRA_SPACE_TKIP, skb->data, hdrlen); - skb_pull(skb, WL1271_TKIP_IV_SPACE); + skb_pull(skb, WL1271_EXTRA_SPACE_TKIP); } info->status.rates[0].idx = -1; @@ -1031,6 +1044,7 @@ void wl12xx_tx_reset(struct wl1271 *wl, bool reset_tx_queues) void wl1271_tx_flush(struct wl1271 *wl) { unsigned long timeout; + int i; timeout = jiffies + usecs_to_jiffies(WL1271_TX_FLUSH_TIMEOUT); while (!time_after(jiffies, timeout)) { @@ -1048,6 +1062,12 @@ void wl1271_tx_flush(struct wl1271 *wl) } wl1271_warning("Unable to flush all TX buffers, timed out."); + + /* forcibly flush all Tx buffers on our queues */ + mutex_lock(&wl->mutex); + for (i = 0; i < WL12XX_MAX_LINKS; i++) + wl1271_tx_reset_link_queues(wl, i); + mutex_unlock(&wl->mutex); } u32 wl1271_tx_min_rate_get(struct wl1271 *wl, u32 rate_set) diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h index 2dbb24e6d54..5cf8c32d40d 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -39,6 +39,7 @@ #define TX_HW_ATTR_LAST_WORD_PAD (BIT(10) | BIT(11)) #define TX_HW_ATTR_TX_CMPLT_REQ BIT(12) #define TX_HW_ATTR_TX_DUMMY_REQ BIT(13) +#define TX_HW_ATTR_HOST_ENCRYPT BIT(14) #define TX_HW_ATTR_OFST_SAVE_RETRIES 0 #define TX_HW_ATTR_OFST_HEADER_PAD 1 @@ -51,7 +52,9 @@ #define TX_HW_RESULT_QUEUE_LEN_MASK 0xf #define WL1271_TX_ALIGN_TO 4 -#define WL1271_TKIP_IV_SPACE 4 +#define WL1271_EXTRA_SPACE_TKIP 4 +#define WL1271_EXTRA_SPACE_AES 8 +#define WL1271_EXTRA_SPACE_MAX 8 /* Used for management frames and dummy packets */ #define WL1271_TID_MGMT 7 @@ -224,5 +227,6 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids); /* from main.c */ void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid); +void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index b2b09cd0202..749a15a75d3 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -35,8 +35,14 @@ #include "conf.h" #include "ini.h" -#define WL127X_FW_NAME "ti-connectivity/wl127x-fw-3.bin" -#define WL128X_FW_NAME "ti-connectivity/wl128x-fw-3.bin" +#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin" +#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin" + +#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin" +#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin" + +#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin" +#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin" /* * wl127x and wl128x are using the same NVS file name. However, the @@ -90,7 +96,13 @@ enum wl1271_state { WL1271_STATE_OFF, WL1271_STATE_ON, - WL1271_STATE_PLT, +}; + +enum wl12xx_fw_type { + WL12XX_FW_TYPE_NONE, + WL12XX_FW_TYPE_NORMAL, + WL12XX_FW_TYPE_MULTI, + WL12XX_FW_TYPE_PLT, }; enum wl1271_partition_type { @@ -247,15 +259,17 @@ enum wl12xx_flags { WL1271_FLAG_PENDING_WORK, WL1271_FLAG_SOFT_GEMINI, WL1271_FLAG_RECOVERY_IN_PROGRESS, + WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, + WL1271_FLAG_INTENDED_FW_RECOVERY, }; enum wl12xx_vif_flags { WLVIF_FLAG_INITIALIZED, WLVIF_FLAG_STA_ASSOCIATED, + WLVIF_FLAG_STA_AUTHORIZED, WLVIF_FLAG_IBSS_JOINED, WLVIF_FLAG_AP_STARTED, - WLVIF_FLAG_PSM, - WLVIF_FLAG_PSM_REQUESTED, + WLVIF_FLAG_IN_PS, WLVIF_FLAG_STA_STATE_SENT, WLVIF_FLAG_RX_STREAMING_STARTED, WLVIF_FLAG_PSPOLL_FAILURE, @@ -295,6 +309,9 @@ struct wl1271 { spinlock_t wl_lock; enum wl1271_state state; + enum wl12xx_fw_type fw_type; + bool plt; + u8 last_vif_count; struct mutex mutex; unsigned long flags; @@ -313,7 +330,12 @@ struct wl1271 { s8 hw_pg_ver; - u8 mac_addr[ETH_ALEN]; + /* address read from the fuse ROM */ + u32 fuse_oui_addr; + u32 fuse_nic_addr; + + /* we have up to 2 MAC addresses */ + struct mac_address addresses[2]; int channel; u8 system_hlid; @@ -425,8 +447,6 @@ struct wl1271 { struct wl12xx_fw_status *fw_status; struct wl1271_tx_hw_res_if *tx_res_if; - struct ieee80211_vif *vif; - /* Current chipset configuration */ struct conf_drv_settings conf; @@ -434,8 +454,6 @@ struct wl1271 { bool enable_11a; - struct list_head list; - /* Most recently reported noise in dBm */ s8 noise; @@ -477,6 +495,9 @@ struct wl1271 { /* last wlvif we transmitted from */ struct wl12xx_vif *last_wlvif; + + /* work to fire when Tx is stuck */ + struct delayed_work tx_watchdog_work; }; struct wl1271_station { @@ -503,6 +524,8 @@ struct wl12xx_vif { u8 basic_rate_idx; u8 ap_rate_idx; u8 p2p_rate_idx; + + bool qos; } sta; struct { u8 global_hlid; @@ -560,12 +583,6 @@ struct wl12xx_vif { /* Session counter for the chipset */ int session_counter; - struct completion *ps_compl; - struct delayed_work pspoll_work; - - /* counter for ps-poll delivery failures */ - int ps_poll_failures; - /* retry counter for PSM entries */ u8 psm_entry_retry; @@ -575,6 +592,10 @@ struct wl12xx_vif { int rssi_thold; int last_rssi_event; + /* save the current encryption type for auto-arp config */ + u8 encryption_type; + __be32 ip_addr; + /* RX BA constraint value */ bool ba_support; bool ba_allowed; diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h index 8f0ffaf6230..22b0bc98d7b 100644 --- a/drivers/net/wireless/wl12xx/wl12xx_80211.h +++ b/drivers/net/wireless/wl12xx/wl12xx_80211.h @@ -117,7 +117,7 @@ struct wl12xx_ps_poll_template { } __packed; struct wl12xx_arp_rsp_template { - struct ieee80211_hdr_3addr hdr; + /* not including ieee80211 header */ u8 llc_hdr[sizeof(rfc1042_header)]; __be16 llc_type; diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 98a574a4a46..9fcde36d501 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -306,9 +306,19 @@ int zd_op_start(struct ieee80211_hw *hw) r = set_mc_hash(mac); if (r) goto disable_int; + + /* Wait after setting the multicast hash table and powering on + * the radio otherwise interface bring up will fail. This matches + * what the vendor driver did. + */ + msleep(10); + r = zd_chip_switch_radio_on(chip); - if (r < 0) + if (r < 0) { + dev_err(zd_chip_dev(chip), + "%s: failed to set radio on\n", __func__); goto disable_int; + } r = zd_chip_enable_rxtx(chip); if (r < 0) goto disable_radio; |