diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/net/wireless/ath/ath5k')
32 files changed, 0 insertions, 26756 deletions
diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/Kconfig b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/Kconfig deleted file mode 100644 index e18a9aa7..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/Kconfig +++ /dev/null @@ -1,66 +0,0 @@ -config ATH5K - tristate "Atheros 5xxx wireless cards support" - depends on (PCI || ATHEROS_AR231X) && MAC80211 - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS - select AVERAGE - select ATH5K_AHB if (ATHEROS_AR231X && !PCI) - select ATH5K_PCI if (!ATHEROS_AR231X && PCI) - ---help--- - This module adds support for wireless adapters based on - Atheros 5xxx chipset. - - Currently the following chip versions are supported: - - MAC: AR5211 AR5212 - PHY: RF5111/2111 RF5112/2112 RF5413/2413 - - This driver uses the kernel's mac80211 subsystem. - - If you choose to build a module, it'll be called ath5k. Say M if - unsure. - -config ATH5K_DEBUG - bool "Atheros 5xxx debugging" - depends on ATH5K - ---help--- - Atheros 5xxx debugging messages. - - Say Y, if and you will get debug options for ath5k. - To use this, you need to mount debugfs: - - mount -t debugfs debug /sys/kernel/debug - - You will get access to files under: - /sys/kernel/debug/ath5k/phy0/ - - To enable debug, pass the debug level to the debug module - parameter. For example: - - modprobe ath5k debug=0x00000400 - -config ATH5K_TRACER - bool "Atheros 5xxx tracer" - depends on ATH5K - depends on EVENT_TRACING - ---help--- - Say Y here to enable tracepoints for the ath5k driver - using the kernel tracing infrastructure. Select this - option if you are interested in debugging the driver. - - If unsure, say N. - -config ATH5K_AHB - bool "Atheros 5xxx AHB bus support" - depends on (ATHEROS_AR231X && !PCI) - ---help--- - This adds support for WiSoC type chipsets of the 5xxx Atheros - family. - -config ATH5K_PCI - bool "Atheros 5xxx PCI bus support" - depends on (!ATHEROS_AR231X && PCI) - ---help--- - This adds support for PCI type chipsets of the 5xxx Atheros - family. diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/Makefile b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/Makefile deleted file mode 100644 index f60b3899..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -ath5k-y += caps.o -ath5k-y += initvals.o -ath5k-y += eeprom.o -ath5k-y += gpio.o -ath5k-y += desc.o -ath5k-y += dma.o -ath5k-y += qcu.o -ath5k-y += pcu.o -ath5k-y += phy.o -ath5k-y += reset.o -ath5k-y += attach.o -ath5k-y += base.o -ath5k-y += led.o -ath5k-y += rfkill.o -ath5k-y += ani.o -ath5k-y += sysfs.o -ath5k-y += mac80211-ops.o -ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o -ath5k-$(CONFIG_ATH5K_AHB) += ahb.o -ath5k-$(CONFIG_ATH5K_PCI) += pci.o -obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ahb.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ahb.c deleted file mode 100644 index aec33cc2..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ahb.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2008-2009 Atheros Communications Inc. - * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> - * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> - * - * 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/nl80211.h> -#include <linux/platform_device.h> -#include <linux/etherdevice.h> -#include <linux/export.h> -#include <ar231x_platform.h> -#include "ath5k.h" -#include "debug.h" -#include "base.h" -#include "reg.h" - -/* return bus cachesize in 4B word units */ -static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz) -{ - *csz = L1_CACHE_BYTES >> 2; -} - -static bool -ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) -{ - struct ath5k_hw *ah = common->priv; - struct platform_device *pdev = to_platform_device(ah->dev); - struct ar231x_board_config *bcfg = pdev->dev.platform_data; - u16 *eeprom, *eeprom_end; - - - - bcfg = pdev->dev.platform_data; - eeprom = (u16 *) bcfg->radio; - eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ; - - eeprom += off; - if (eeprom > eeprom_end) - return false; - - *data = *eeprom; - return true; -} - -int ath5k_hw_read_srev(struct ath5k_hw *ah) -{ - struct platform_device *pdev = to_platform_device(ah->dev); - struct ar231x_board_config *bcfg = pdev->dev.platform_data; - ah->ah_mac_srev = bcfg->devid; - return 0; -} - -static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) -{ - struct platform_device *pdev = to_platform_device(ah->dev); - struct ar231x_board_config *bcfg = pdev->dev.platform_data; - u8 *cfg_mac; - - if (to_platform_device(ah->dev)->id == 0) - cfg_mac = bcfg->config->wlan0_mac; - else - cfg_mac = bcfg->config->wlan1_mac; - - memcpy(mac, cfg_mac, ETH_ALEN); - return 0; -} - -static const struct ath_bus_ops ath_ahb_bus_ops = { - .ath_bus_type = ATH_AHB, - .read_cachesize = ath5k_ahb_read_cachesize, - .eeprom_read = ath5k_ahb_eeprom_read, - .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, -}; - -/*Initialization*/ -static int ath_ahb_probe(struct platform_device *pdev) -{ - struct ar231x_board_config *bcfg = pdev->dev.platform_data; - struct ath5k_hw *ah; - struct ieee80211_hw *hw; - struct resource *res; - void __iomem *mem; - int irq; - int ret = 0; - u32 reg; - - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "no platform data specified\n"); - ret = -EINVAL; - goto err_out; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no memory resource found\n"); - ret = -ENXIO; - goto err_out; - } - - mem = ioremap_nocache(res->start, resource_size(res)); - if (mem == NULL) { - dev_err(&pdev->dev, "ioremap failed\n"); - ret = -ENOMEM; - goto err_out; - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (res == NULL) { - dev_err(&pdev->dev, "no IRQ resource found\n"); - ret = -ENXIO; - goto err_iounmap; - } - - irq = res->start; - - hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops); - if (hw == NULL) { - dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); - ret = -ENOMEM; - goto err_iounmap; - } - - ah = hw->priv; - ah->hw = hw; - ah->dev = &pdev->dev; - ah->iobase = mem; - ah->irq = irq; - ah->devid = bcfg->devid; - - if (bcfg->devid >= AR5K_SREV_AR2315_R6) { - /* Enable WMAC AHB arbitration */ - reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); - reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; - iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); - - /* Enable global WMAC swapping */ - reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP); - reg |= AR5K_AR2315_BYTESWAP_WMAC; - iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); - } else { - /* Enable WMAC DMA access (assuming 5312 or 231x*/ - /* TODO: check other platforms */ - 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; - iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); - - /* - * On a dual-band AR5312, the multiband radio is only - * used as pass-through. Disable 2 GHz support in the - * driver for it - */ - if (to_platform_device(ah->dev)->id == 0 && - (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) == - (BD_WLAN1 | BD_WLAN0)) - ah->ah_capabilities.cap_needs_2GHz_ovr = true; - else - ah->ah_capabilities.cap_needs_2GHz_ovr = false; - } - - ret = ath5k_init_ah(ah, &ath_ahb_bus_ops); - if (ret != 0) { - dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); - ret = -ENODEV; - goto err_free_hw; - } - - platform_set_drvdata(pdev, hw); - - return 0; - - err_free_hw: - ieee80211_free_hw(hw); - platform_set_drvdata(pdev, NULL); - err_iounmap: - iounmap(mem); - err_out: - return ret; -} - -static int ath_ahb_remove(struct platform_device *pdev) -{ - struct ar231x_board_config *bcfg = pdev->dev.platform_data; - struct ieee80211_hw *hw = platform_get_drvdata(pdev); - struct ath5k_hw *ah; - u32 reg; - - if (!hw) - return 0; - - ah = hw->priv; - - if (bcfg->devid >= AR5K_SREV_AR2315_R6) { - /* Disable WMAC AHB arbitration */ - reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); - reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; - iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); - } else { - /*Stop DMA access */ - 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; - iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); - } - - ath5k_deinit_ah(ah); - iounmap(ah->iobase); - platform_set_drvdata(pdev, NULL); - ieee80211_free_hw(hw); - - return 0; -} - -static struct platform_driver ath_ahb_driver = { - .probe = ath_ahb_probe, - .remove = ath_ahb_remove, - .driver = { - .name = "ar231x-wmac", - .owner = THIS_MODULE, - }, -}; - -static int __init -ath5k_ahb_init(void) -{ - return platform_driver_register(&ath_ahb_driver); -} - -static void __exit -ath5k_ahb_exit(void) -{ - platform_driver_unregister(&ath_ahb_driver); -} - -module_init(ath5k_ahb_init); -module_exit(ath5k_ahb_exit); diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ani.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ani.c deleted file mode 100644 index 35e93704..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ani.c +++ /dev/null @@ -1,760 +0,0 @@ -/* - * Copyright (C) 2010 Bruno Randolf <br1@einfach.org> - * - * 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 "ath5k.h" -#include "reg.h" -#include "debug.h" -#include "ani.h" - -/** - * DOC: Basic ANI Operation - * - * Adaptive Noise Immunity (ANI) controls five noise immunity parameters - * depending on the amount of interference in the environment, increasing - * or reducing sensitivity as necessary. - * - * The parameters are: - * - * - "noise immunity" - * - * - "spur immunity" - * - * - "firstep level" - * - * - "OFDM weak signal detection" - * - * - "CCK weak signal detection" - * - * Basically we look at the amount of ODFM and CCK timing errors we get and then - * raise or lower immunity accordingly by setting one or more of these - * parameters. - * - * Newer chipsets have PHY error counters in hardware which will generate a MIB - * interrupt when they overflow. Older hardware has too enable PHY error frames - * by setting a RX flag and then count every single PHY error. When a specified - * threshold of errors has been reached we will raise immunity. - * Also we regularly check the amount of errors and lower or raise immunity as - * necessary. - */ - - -/***********************\ -* ANI parameter control * -\***********************/ - -/** - * ath5k_ani_set_noise_immunity_level() - Set noise immunity level - * @ah: The &struct ath5k_hw - * @level: level between 0 and @ATH5K_ANI_MAX_NOISE_IMM_LVL - */ -void -ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) -{ - /* TODO: - * ANI documents suggest the following five levels to use, but the HAL - * and ath9k use only the last two levels, making this - * essentially an on/off option. There *may* be a reason for this (???), - * so i stick with the HAL version for now... - */ -#if 0 - static const s8 lo[] = { -52, -56, -60, -64, -70 }; - static const s8 hi[] = { -18, -18, -16, -14, -12 }; - static const s8 sz[] = { -34, -41, -48, -55, -62 }; - static const s8 fr[] = { -70, -72, -75, -78, -80 }; -#else - static const s8 lo[] = { -64, -70 }; - static const s8 hi[] = { -14, -12 }; - static const s8 sz[] = { -55, -62 }; - static const s8 fr[] = { -78, -80 }; -#endif - if (level < 0 || level >= ARRAY_SIZE(sz)) { - ATH5K_ERR(ah, "noise immunity level %d out of range", - level); - return; - } - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, - AR5K_PHY_DESIRED_SIZE_TOT, sz[level]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE, - AR5K_PHY_AGCCOARSE_LO, lo[level]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE, - AR5K_PHY_AGCCOARSE_HI, hi[level]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG, - AR5K_PHY_SIG_FIRPWR, fr[level]); - - ah->ani_state.noise_imm_level = level; - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level); -} - -/** - * ath5k_ani_set_spur_immunity_level() - Set spur immunity level - * @ah: The &struct ath5k_hw - * @level: level between 0 and @max_spur_level (the maximum level is dependent - * on the chip revision). - */ -void -ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) -{ - static const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; - - if (level < 0 || level >= ARRAY_SIZE(val) || - level > ah->ani_state.max_spur_level) { - ATH5K_ERR(ah, "spur immunity level %d out of range", - level); - return; - } - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, - AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]); - - ah->ani_state.spur_level = level; - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level); -} - -/** - * ath5k_ani_set_firstep_level() - Set "firstep" level - * @ah: The &struct ath5k_hw - * @level: level between 0 and @ATH5K_ANI_MAX_FIRSTEP_LVL - */ -void -ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) -{ - static const int val[] = { 0, 4, 8 }; - - if (level < 0 || level >= ARRAY_SIZE(val)) { - ATH5K_ERR(ah, "firstep level %d out of range", level); - return; - } - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG, - AR5K_PHY_SIG_FIRSTEP, val[level]); - - ah->ani_state.firstep_level = level; - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "new level %d", level); -} - -/** - * ath5k_ani_set_ofdm_weak_signal_detection() - Set OFDM weak signal detection - * @ah: The &struct ath5k_hw - * @on: turn on or off - */ -void -ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) -{ - static const int m1l[] = { 127, 50 }; - static const int m2l[] = { 127, 40 }; - static const int m1[] = { 127, 0x4d }; - static const int m2[] = { 127, 0x40 }; - static const int m2cnt[] = { 31, 16 }; - static const int m2lcnt[] = { 63, 48 }; - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, - AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, - AR5K_PHY_WEAK_OFDM_LOW_THR_M2, m2l[on]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR, - AR5K_PHY_WEAK_OFDM_HIGH_THR_M1, m1[on]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR, - AR5K_PHY_WEAK_OFDM_HIGH_THR_M2, m2[on]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR, - AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT, m2cnt[on]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, - AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT, m2lcnt[on]); - - if (on) - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, - AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN); - else - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, - AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN); - - ah->ani_state.ofdm_weak_sig = on; - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "turned %s", - on ? "on" : "off"); -} - -/** - * ath5k_ani_set_cck_weak_signal_detection() - Set CCK weak signal detection - * @ah: The &struct ath5k_hw - * @on: turn on or off - */ -void -ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on) -{ - static const int val[] = { 8, 6 }; - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR, - AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]); - ah->ani_state.cck_weak_sig = on; - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "turned %s", - on ? "on" : "off"); -} - - -/***************\ -* ANI algorithm * -\***************/ - -/** - * ath5k_ani_raise_immunity() - Increase noise immunity - * @ah: The &struct ath5k_hw - * @as: The &struct ath5k_ani_state - * @ofdm_trigger: If this is true we are called because of too many OFDM errors, - * the algorithm will tune more parameters then. - * - * Try to raise noise immunity (=decrease sensitivity) in several steps - * depending on the average RSSI of the beacons we received. - */ -static void -ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, - bool ofdm_trigger) -{ - int rssi = ewma_read(&ah->ah_beacon_rssi_avg); - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "raise immunity (%s)", - ofdm_trigger ? "ODFM" : "CCK"); - - /* first: raise noise immunity */ - if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) { - ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1); - return; - } - - /* only OFDM: raise spur immunity level */ - if (ofdm_trigger && - as->spur_level < ah->ani_state.max_spur_level) { - ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1); - return; - } - - /* AP mode */ - if (ah->opmode == NL80211_IFTYPE_AP) { - if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) - ath5k_ani_set_firstep_level(ah, as->firstep_level + 1); - return; - } - - /* STA and IBSS mode */ - - /* TODO: for IBSS mode it would be better to keep a beacon RSSI average - * per each neighbour node and use the minimum of these, to make sure we - * don't shut out a remote node by raising immunity too high. */ - - if (rssi > ATH5K_ANI_RSSI_THR_HIGH) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "beacon RSSI high"); - /* only OFDM: beacon RSSI is high, we can disable ODFM weak - * signal detection */ - 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; - } - /* as a last resort or CCK: raise firstep level */ - if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) { - ath5k_ani_set_firstep_level(ah, as->firstep_level + 1); - return; - } - } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) { - /* beacon RSSI in mid range, we need OFDM weak signal detect, - * but can raise firstep level */ - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "beacon RSSI mid"); - 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); - return; - } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) { - /* beacon RSSI is low. in B/G mode turn of OFDM weak signal - * 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) - ath5k_ani_set_ofdm_weak_signal_detection(ah, false); - if (as->firstep_level > 0) - ath5k_ani_set_firstep_level(ah, 0); - return; - } - - /* TODO: why not?: - if (as->cck_weak_sig == true) { - ath5k_ani_set_cck_weak_signal_detection(ah, false); - } - */ -} - -/** - * ath5k_ani_lower_immunity() - Decrease noise immunity - * @ah: The &struct ath5k_hw - * @as: The &struct ath5k_ani_state - * - * Try to lower noise immunity (=increase sensitivity) in several steps - * depending on the average RSSI of the beacons we received. - */ -static void -ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) -{ - int rssi = ewma_read(&ah->ah_beacon_rssi_avg); - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "lower immunity"); - - if (ah->opmode == NL80211_IFTYPE_AP) { - /* AP mode */ - if (as->firstep_level > 0) { - ath5k_ani_set_firstep_level(ah, as->firstep_level - 1); - return; - } - } else { - /* STA and IBSS mode (see TODO above) */ - if (rssi > ATH5K_ANI_RSSI_THR_HIGH) { - /* beacon signal is high, leave OFDM weak signal - * detection off or it may oscillate - * TODO: who said it's off??? */ - } 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) { - ath5k_ani_set_ofdm_weak_signal_detection(ah, - true); - return; - } - if (as->firstep_level > 0) { - ath5k_ani_set_firstep_level(ah, - as->firstep_level - 1); - return; - } - } else { - /* beacon signal is low: only reduce firstep level */ - if (as->firstep_level > 0) { - ath5k_ani_set_firstep_level(ah, - as->firstep_level - 1); - return; - } - } - } - - /* all modes */ - if (as->spur_level > 0) { - ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1); - return; - } - - /* finally, reduce noise immunity */ - if (as->noise_imm_level > 0) { - ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1); - return; - } -} - -/** - * ath5k_hw_ani_get_listen_time() - Update counters and return listening time - * @ah: The &struct ath5k_hw - * @as: The &struct ath5k_ani_state - * - * Return an approximation of the time spent "listening" in milliseconds (ms) - * since the last call of this function. - * Save a snapshot of the counter values for debugging/statistics. - */ -static int -ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) -{ - struct ath_common *common = ath5k_hw_common(ah); - int listen; - - spin_lock_bh(&common->cc_lock); - - ath_hw_cycle_counters_update(common); - memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc)); - - /* clears common->cc_ani */ - listen = ath_hw_get_listen_time(common); - - spin_unlock_bh(&common->cc_lock); - - return listen; -} - -/** - * ath5k_ani_save_and_clear_phy_errors() - Clear and save PHY error counters - * @ah: The &struct ath5k_hw - * @as: The &struct ath5k_ani_state - * - * Clear the PHY error counters as soon as possible, since this might be called - * from a MIB interrupt and we want to make sure we don't get interrupted again. - * Add the count of CCK and OFDM errors to our internal state, so it can be used - * by the algorithm later. - * - * Will be called from interrupt and tasklet context. - * Returns 0 if both counters are zero. - */ -static int -ath5k_ani_save_and_clear_phy_errors(struct ath5k_hw *ah, - struct ath5k_ani_state *as) -{ - unsigned int ofdm_err, cck_err; - - if (!ah->ah_capabilities.cap_has_phyerr_counters) - return 0; - - ofdm_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1); - cck_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2); - - /* reset counters first, we might be in a hurry (interrupt) */ - ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH, - AR5K_PHYERR_CNT1); - ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH, - AR5K_PHYERR_CNT2); - - ofdm_err = ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ofdm_err); - cck_err = ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - cck_err); - - /* sometimes both can be zero, especially when there is a superfluous - * second interrupt. detect that here and return an error. */ - if (ofdm_err <= 0 && cck_err <= 0) - return 0; - - /* avoid negative values should one of the registers overflow */ - if (ofdm_err > 0) { - as->ofdm_errors += ofdm_err; - as->sum_ofdm_errors += ofdm_err; - } - if (cck_err > 0) { - as->cck_errors += cck_err; - as->sum_cck_errors += cck_err; - } - return 1; -} - -/** - * ath5k_ani_period_restart() - Restart ANI period - * @as: The &struct ath5k_ani_state - * - * Just reset counters, so they are clear for the next "ani period". - */ -static void -ath5k_ani_period_restart(struct ath5k_ani_state *as) -{ - /* keep last values for debugging */ - as->last_ofdm_errors = as->ofdm_errors; - as->last_cck_errors = as->cck_errors; - as->last_listen = as->listen_time; - - as->ofdm_errors = 0; - as->cck_errors = 0; - as->listen_time = 0; -} - -/** - * ath5k_ani_calibration() - The main ANI calibration function - * @ah: The &struct ath5k_hw - * - * We count OFDM and CCK errors relative to the time where we did not send or - * receive ("listen" time) and raise or lower immunity accordingly. - * This is called regularly (every second) from the calibration timer, but also - * when an error threshold has been reached. - * - * In order to synchronize access from different contexts, this should be - * called only indirectly by scheduling the ANI tasklet! - */ -void -ath5k_ani_calibration(struct ath5k_hw *ah) -{ - struct ath5k_ani_state *as = &ah->ani_state; - int listen, ofdm_high, ofdm_low, cck_high, cck_low; - - /* get listen time since last call and add it to the counter because we - * might not have restarted the "ani period" last time. - * always do this to calculate the busy time also in manual mode */ - listen = ath5k_hw_ani_get_listen_time(ah, as); - as->listen_time += listen; - - if (as->ani_mode != ATH5K_ANI_MODE_AUTO) - return; - - ath5k_ani_save_and_clear_phy_errors(ah, as); - - ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; - cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000; - ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000; - cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000; - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "listen %d (now %d)", as->listen_time, listen); - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "check high ofdm %d/%d cck %d/%d", - as->ofdm_errors, ofdm_high, as->cck_errors, cck_high); - - if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) { - /* too many PHY errors - we have to raise immunity */ - bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false; - ath5k_ani_raise_immunity(ah, as, ofdm_flag); - ath5k_ani_period_restart(as); - - } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) { - /* If more than 5 (TODO: why 5?) periods have passed and we got - * relatively little errors we can try to lower immunity */ - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "check low ofdm %d/%d cck %d/%d", - as->ofdm_errors, ofdm_low, as->cck_errors, cck_low); - - if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low) - ath5k_ani_lower_immunity(ah, as); - - ath5k_ani_period_restart(as); - } -} - - -/*******************\ -* Interrupt handler * -\*******************/ - -/** - * ath5k_ani_mib_intr() - Interrupt handler for ANI MIB counters - * @ah: The &struct ath5k_hw - * - * Just read & reset the registers quickly, so they don't generate more - * interrupts, save the counters and schedule the tasklet to decide whether - * to raise immunity or not. - * - * We just need to handle PHY error counters, ath5k_hw_update_mib_counters() - * should take care of all "normal" MIB interrupts. - */ -void -ath5k_ani_mib_intr(struct ath5k_hw *ah) -{ - struct ath5k_ani_state *as = &ah->ani_state; - - /* nothing to do here if HW does not have PHY error counters - they - * can't be the reason for the MIB interrupt then */ - if (!ah->ah_capabilities.cap_has_phyerr_counters) - return; - - /* not in use but clear anyways */ - ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT); - ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT); - - if (ah->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) - return; - - /* If one of the errors triggered, we can get a superfluous second - * interrupt, even though we have already reset the register. The - * function detects that so we can return early. */ - if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) - return; - - if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH || - as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH) - tasklet_schedule(&ah->ani_tasklet); -} - -/** - * ath5k_ani_phy_error_report - Used by older HW to report PHY errors - * - * @ah: The &struct ath5k_hw - * @phyerr: One of enum ath5k_phy_error_code - * - * This is used by hardware without PHY error counters to report PHY errors - * on a frame-by-frame basis, instead of the interrupt. - */ -void -ath5k_ani_phy_error_report(struct ath5k_hw *ah, - enum ath5k_phy_error_code phyerr) -{ - struct ath5k_ani_state *as = &ah->ani_state; - - if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) { - as->ofdm_errors++; - if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH) - tasklet_schedule(&ah->ani_tasklet); - } else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) { - as->cck_errors++; - if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH) - tasklet_schedule(&ah->ani_tasklet); - } -} - - -/****************\ -* Initialization * -\****************/ - -/** - * ath5k_enable_phy_err_counters() - Enable PHY error counters - * @ah: The &struct ath5k_hw - * - * Enable PHY error counters for OFDM and CCK timing errors. - */ -static void -ath5k_enable_phy_err_counters(struct ath5k_hw *ah) -{ - ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH, - AR5K_PHYERR_CNT1); - ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH, - AR5K_PHYERR_CNT2); - ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHYERR_CNT1_MASK); - ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_CCK, AR5K_PHYERR_CNT2_MASK); - - /* not in use */ - ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT); - ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT); -} - -/** - * ath5k_disable_phy_err_counters() - Disable PHY error counters - * @ah: The &struct ath5k_hw - * - * Disable PHY error counters for OFDM and CCK timing errors. - */ -static void -ath5k_disable_phy_err_counters(struct ath5k_hw *ah) -{ - ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1); - ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2); - ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1_MASK); - ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2_MASK); - - /* not in use */ - ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT); - ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT); -} - -/** - * ath5k_ani_init() - Initialize ANI - * @ah: The &struct ath5k_hw - * @mode: One of enum ath5k_ani_mode - * - * Initialize ANI according to mode. - */ -void -ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode) -{ - /* ANI is only possible on 5212 and newer */ - if (ah->ah_version < AR5K_AR5212) - return; - - if (mode < ATH5K_ANI_MODE_OFF || mode > ATH5K_ANI_MODE_AUTO) { - ATH5K_ERR(ah, "ANI mode %d out of range", mode); - return; - } - - /* clear old state information */ - memset(&ah->ani_state, 0, sizeof(ah->ani_state)); - - /* older hardware has more spur levels than newer */ - if (ah->ah_mac_srev < AR5K_SREV_AR2414) - ah->ani_state.max_spur_level = 7; - else - ah->ani_state.max_spur_level = 2; - - /* initial values for our ani parameters */ - if (mode == ATH5K_ANI_MODE_OFF) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI off\n"); - } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "ANI manual low -> high sensitivity\n"); - ath5k_ani_set_noise_immunity_level(ah, 0); - ath5k_ani_set_spur_immunity_level(ah, 0); - ath5k_ani_set_firstep_level(ah, 0); - ath5k_ani_set_ofdm_weak_signal_detection(ah, true); - ath5k_ani_set_cck_weak_signal_detection(ah, true); - } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, - "ANI manual high -> low sensitivity\n"); - ath5k_ani_set_noise_immunity_level(ah, - ATH5K_ANI_MAX_NOISE_IMM_LVL); - ath5k_ani_set_spur_immunity_level(ah, - ah->ani_state.max_spur_level); - ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL); - ath5k_ani_set_ofdm_weak_signal_detection(ah, false); - ath5k_ani_set_cck_weak_signal_detection(ah, false); - } else if (mode == ATH5K_ANI_MODE_AUTO) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_ANI, "ANI auto\n"); - ath5k_ani_set_noise_immunity_level(ah, 0); - ath5k_ani_set_spur_immunity_level(ah, 0); - ath5k_ani_set_firstep_level(ah, 0); - ath5k_ani_set_ofdm_weak_signal_detection(ah, true); - ath5k_ani_set_cck_weak_signal_detection(ah, false); - } - - /* newer hardware has PHY error counter registers which we can use to - * get OFDM and CCK error counts. older hardware has to set rxfilter and - * report every single PHY error by calling ath5k_ani_phy_error_report() - */ - if (mode == ATH5K_ANI_MODE_AUTO) { - if (ah->ah_capabilities.cap_has_phyerr_counters) - ath5k_enable_phy_err_counters(ah); - else - ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) | - AR5K_RX_FILTER_PHYERR); - } else { - if (ah->ah_capabilities.cap_has_phyerr_counters) - ath5k_disable_phy_err_counters(ah); - else - ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) & - ~AR5K_RX_FILTER_PHYERR); - } - - ah->ani_state.ani_mode = mode; -} - - -/**************\ -* Debug output * -\**************/ - -#ifdef CONFIG_ATH5K_DEBUG - -/** - * ath5k_ani_print_counters() - Print ANI counters - * @ah: The &struct ath5k_hw - * - * Used for debugging ANI - */ -void -ath5k_ani_print_counters(struct ath5k_hw *ah) -{ - /* clears too */ - printk(KERN_NOTICE "ACK fail\t%d\n", - ath5k_hw_reg_read(ah, AR5K_ACK_FAIL)); - printk(KERN_NOTICE "RTS fail\t%d\n", - ath5k_hw_reg_read(ah, AR5K_RTS_FAIL)); - printk(KERN_NOTICE "RTS success\t%d\n", - ath5k_hw_reg_read(ah, AR5K_RTS_OK)); - printk(KERN_NOTICE "FCS error\t%d\n", - ath5k_hw_reg_read(ah, AR5K_FCS_FAIL)); - - /* no clear */ - printk(KERN_NOTICE "tx\t%d\n", - ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX)); - printk(KERN_NOTICE "rx\t%d\n", - ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX)); - printk(KERN_NOTICE "busy\t%d\n", - ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR)); - printk(KERN_NOTICE "cycles\t%d\n", - ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE)); - - printk(KERN_NOTICE "AR5K_PHYERR_CNT1\t%d\n", - ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1)); - printk(KERN_NOTICE "AR5K_PHYERR_CNT2\t%d\n", - ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2)); - printk(KERN_NOTICE "AR5K_OFDM_FIL_CNT\t%d\n", - ath5k_hw_reg_read(ah, AR5K_OFDM_FIL_CNT)); - printk(KERN_NOTICE "AR5K_CCK_FIL_CNT\t%d\n", - ath5k_hw_reg_read(ah, AR5K_CCK_FIL_CNT)); -} - -#endif diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ani.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ani.h deleted file mode 100644 index 21aa3554..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ani.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2010 Bruno Randolf <br1@einfach.org> - * - * 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 ANI_H -#define ANI_H - -#include "../ath.h" - -enum ath5k_phy_error_code; - -/* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */ -#define ATH5K_ANI_LISTEN_PERIOD 100 -#define ATH5K_ANI_OFDM_TRIG_HIGH 500 -#define ATH5K_ANI_OFDM_TRIG_LOW 200 -#define ATH5K_ANI_CCK_TRIG_HIGH 200 -#define ATH5K_ANI_CCK_TRIG_LOW 100 - -/* average beacon RSSI thresholds */ -#define ATH5K_ANI_RSSI_THR_HIGH 40 -#define ATH5K_ANI_RSSI_THR_LOW 7 - -/* maximum available levels */ -#define ATH5K_ANI_MAX_FIRSTEP_LVL 2 -#define ATH5K_ANI_MAX_NOISE_IMM_LVL 1 - - -/** - * enum ath5k_ani_mode - mode for ANI / noise sensitivity - * - * @ATH5K_ANI_MODE_OFF: Turn ANI off. This can be useful to just stop the ANI - * algorithm after it has been on auto mode. - * @ATH5K_ANI_MODE_MANUAL_LOW: Manually set all immunity parameters to low, - * maximizing sensitivity. ANI will not run. - * @ATH5K_ANI_MODE_MANUAL_HIGH: Manually set all immunity parameters to high, - * minimizing sensitivity. ANI will not run. - * @ATH5K_ANI_MODE_AUTO: Automatically control immunity parameters based on the - * amount of OFDM and CCK frame errors (default). - */ -enum ath5k_ani_mode { - ATH5K_ANI_MODE_OFF = 0, - ATH5K_ANI_MODE_MANUAL_LOW = 1, - ATH5K_ANI_MODE_MANUAL_HIGH = 2, - ATH5K_ANI_MODE_AUTO = 3 -}; - - -/** - * struct ath5k_ani_state - ANI state and associated counters - * @ani_mode: One of enum ath5k_ani_mode - * @noise_imm_level: Noise immunity level - * @spur_level: Spur immunity level - * @firstep_level: FIRstep level - * @ofdm_weak_sig: OFDM weak signal detection state (on/off) - * @cck_weak_sig: CCK weak signal detection state (on/off) - * @max_spur_level: Max spur immunity level (chip specific) - * @listen_time: Listen time - * @ofdm_errors: OFDM timing error count - * @cck_errors: CCK timing error count - * @last_cc: The &struct ath_cycle_counters (for stats) - * @last_listen: Listen time from previous run (for stats) - * @last_ofdm_errors: OFDM timing error count from previous run (for tats) - * @last_cck_errors: CCK timing error count from previous run (for stats) - * @sum_ofdm_errors: Sum of OFDM timing errors (for stats) - * @sum_cck_errors: Sum of all CCK timing errors (for stats) - */ -struct ath5k_ani_state { - enum ath5k_ani_mode ani_mode; - - /* state */ - int noise_imm_level; - int spur_level; - int firstep_level; - bool ofdm_weak_sig; - bool cck_weak_sig; - - int max_spur_level; - - /* used by the algorithm */ - unsigned int listen_time; - unsigned int ofdm_errors; - unsigned int cck_errors; - - /* debug/statistics only: numbers from last ANI calibration */ - struct ath_cycle_counters last_cc; - unsigned int last_listen; - unsigned int last_ofdm_errors; - unsigned int last_cck_errors; - unsigned int sum_ofdm_errors; - unsigned int sum_cck_errors; -}; - -void ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode); -void ath5k_ani_mib_intr(struct ath5k_hw *ah); -void ath5k_ani_calibration(struct ath5k_hw *ah); -void ath5k_ani_phy_error_report(struct ath5k_hw *ah, - enum ath5k_phy_error_code phyerr); - -/* for manual control */ -void ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level); -void ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level); -void ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level); -void ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on); -void ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on); - -void ath5k_ani_print_counters(struct ath5k_hw *ah); - -#endif /* ANI_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ath5k.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ath5k.h deleted file mode 100644 index 8d434b8f..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/ath5k.h +++ /dev/null @@ -1,1710 +0,0 @@ -/* - * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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 _ATH5K_H -#define _ATH5K_H - -/* TODO: Clean up channel debugging (doesn't work anyway) and start - * working on reg. control code using all available eeprom information - * (rev. engineering needed) */ -#define CHAN_DEBUG 0 - -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/types.h> -#include <linux/average.h> -#include <linux/leds.h> -#include <net/mac80211.h> - -/* RX/TX descriptor hw structs - * TODO: Driver part should only see sw structs */ -#include "desc.h" - -/* EEPROM structs/offsets - * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities) - * and clean up common bits, then introduce set/get functions in eeprom.c */ -#include "eeprom.h" -#include "debug.h" -#include "../ath.h" -#include "ani.h" - -/* PCI IDs */ -#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ -#define PCI_DEVICE_ID_ATHEROS_AR5311 0x0011 /* AR5311 */ -#define PCI_DEVICE_ID_ATHEROS_AR5211 0x0012 /* AR5211 */ -#define PCI_DEVICE_ID_ATHEROS_AR5212 0x0013 /* AR5212 */ -#define PCI_DEVICE_ID_3COM_3CRDAG675 0x0013 /* 3CRDAG675 (Atheros AR5212) */ -#define PCI_DEVICE_ID_3COM_2_3CRPAG175 0x0013 /* 3CRPAG175 (Atheros AR5212) */ -#define PCI_DEVICE_ID_ATHEROS_AR5210_AP 0x0207 /* AR5210 (Early) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM 0x1014 /* AR5212 (IBM MiniPCI) */ -#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 0x1107 /* AR5210 (no eeprom) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 0x1113 /* AR5212 (no eeprom) */ -#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 0x1112 /* AR5211 (no eeprom) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 0xf013 /* AR5212 (emulation board) */ -#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 0xff12 /* AR5211 (emulation board) */ -#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 0xf11b /* AR5211 (emulation board) */ -#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ -#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ -#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8 0x0058 /* AR5312 WMAC (AP43-030) */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0014 0x0014 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0015 0x0015 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0016 0x0016 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0017 0x0017 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0018 0x0018 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR5212_0019 0x0019 /* AR5212 compatible */ -#define PCI_DEVICE_ID_ATHEROS_AR2413 0x001a /* AR2413 (Griffin-lite) */ -#define PCI_DEVICE_ID_ATHEROS_AR5413 0x001b /* AR5413 (Eagle) */ -#define PCI_DEVICE_ID_ATHEROS_AR5424 0x001c /* AR5424 (Condor PCI-E) */ -#define PCI_DEVICE_ID_ATHEROS_AR5416 0x0023 /* AR5416 */ -#define PCI_DEVICE_ID_ATHEROS_AR5418 0x0024 /* AR5418 */ - -/****************************\ - GENERIC DRIVER DEFINITIONS -\****************************/ - -#define ATH5K_PRINTF(fmt, ...) \ - printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__) - -#define ATH5K_PRINTK(_sc, _level, _fmt, ...) \ - printk(_level "ath5k %s: " _fmt, \ - ((_sc) && (_sc)->hw) ? wiphy_name((_sc)->hw->wiphy) : "", \ - ##__VA_ARGS__) - -#define ATH5K_PRINTK_LIMIT(_sc, _level, _fmt, ...) do { \ - if (net_ratelimit()) \ - ATH5K_PRINTK(_sc, _level, _fmt, ##__VA_ARGS__); \ - } while (0) - -#define ATH5K_INFO(_sc, _fmt, ...) \ - ATH5K_PRINTK(_sc, KERN_INFO, _fmt, ##__VA_ARGS__) - -#define ATH5K_WARN(_sc, _fmt, ...) \ - ATH5K_PRINTK_LIMIT(_sc, KERN_WARNING, _fmt, ##__VA_ARGS__) - -#define ATH5K_ERR(_sc, _fmt, ...) \ - ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__) - -/* - * AR5K REGISTER ACCESS - */ - -/* Some macros to read/write fields */ - -/* First shift, then mask */ -#define AR5K_REG_SM(_val, _flags) \ - (((_val) << _flags##_S) & (_flags)) - -/* First mask, then shift */ -#define AR5K_REG_MS(_val, _flags) \ - (((_val) & (_flags)) >> _flags##_S) - -/* Some registers can hold multiple values of interest. For this - * reason when we want to write to these registers we must first - * retrieve the values which we do not want to clear (lets call this - * old_data) and then set the register with this and our new_value: - * ( old_data | new_value) */ -#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \ - ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \ - (((_val) << _flags##_S) & (_flags)), _reg) - -#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \ - ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \ - (_mask)) | (_flags), _reg) - -#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \ - ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg) - -#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \ - ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg) - -/* Access QCU registers per queue */ -#define AR5K_REG_READ_Q(ah, _reg, _queue) \ - (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \ - -#define AR5K_REG_WRITE_Q(ah, _reg, _queue) \ - ath5k_hw_reg_write(ah, (1 << _queue), _reg) - -#define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \ - _reg |= 1 << _queue; \ -} while (0) - -#define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \ - _reg &= ~(1 << _queue); \ -} while (0) - -/* Used while writing initvals */ -#define AR5K_REG_WAIT(_i) do { \ - if (_i % 64) \ - udelay(1); \ -} while (0) - -/* - * Some tunable values (these should be changeable by the user) - * TODO: Make use of them and add more options OR use debug/configfs - */ -#define AR5K_TUNE_DMA_BEACON_RESP 2 -#define AR5K_TUNE_SW_BEACON_RESP 10 -#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 -#define AR5K_TUNE_MIN_TX_FIFO_THRES 1 -#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1) -#define AR5K_TUNE_REGISTER_TIMEOUT 20000 -/* Register for RSSI threshold has a mask of 0xff, so 255 seems to - * be the max value. */ -#define AR5K_TUNE_RSSI_THRES 129 -/* This must be set when setting the RSSI threshold otherwise it can - * prevent a reset. If AR5K_RSSI_THR is read after writing to it - * the BMISS_THRES will be seen as 0, seems hardware doesn't keep - * track of it. Max value depends on hardware. For AR5210 this is just 7. - * For AR5211+ this seems to be up to 255. */ -#define AR5K_TUNE_BMISS_THRES 7 -#define AR5K_TUNE_REGISTER_DWELL_TIME 20000 -#define AR5K_TUNE_BEACON_INTERVAL 100 -#define AR5K_TUNE_AIFS 2 -#define AR5K_TUNE_AIFS_11B 2 -#define AR5K_TUNE_AIFS_XR 0 -#define AR5K_TUNE_CWMIN 15 -#define AR5K_TUNE_CWMIN_11B 31 -#define AR5K_TUNE_CWMIN_XR 3 -#define AR5K_TUNE_CWMAX 1023 -#define AR5K_TUNE_CWMAX_11B 1023 -#define AR5K_TUNE_CWMAX_XR 7 -#define AR5K_TUNE_NOISE_FLOOR -72 -#define AR5K_TUNE_CCA_MAX_GOOD_VALUE -95 -#define AR5K_TUNE_MAX_TXPOWER 63 -#define AR5K_TUNE_DEFAULT_TXPOWER 25 -#define AR5K_TUNE_TPC_TXPOWER false -#define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 60000 /* 60 sec */ -#define ATH5K_TUNE_CALIBRATION_INTERVAL_SHORT 10000 /* 10 sec */ -#define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ -#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */ - -#define AR5K_INIT_CARR_SENSE_EN 1 - -/*Swap RX/TX Descriptor for big endian archs*/ -#if defined(__BIG_ENDIAN) -#define AR5K_INIT_CFG ( \ - AR5K_CFG_SWTD | AR5K_CFG_SWRD \ -) -#else -#define AR5K_INIT_CFG 0x00000000 -#endif - -/* Initial values */ -#define AR5K_INIT_CYCRSSI_THR1 2 - -/* Tx retry limit defaults from standard */ -#define AR5K_INIT_RETRY_SHORT 7 -#define AR5K_INIT_RETRY_LONG 4 - -/* Slot time */ -#define AR5K_INIT_SLOT_TIME_TURBO 6 -#define AR5K_INIT_SLOT_TIME_DEFAULT 9 -#define AR5K_INIT_SLOT_TIME_HALF_RATE 13 -#define AR5K_INIT_SLOT_TIME_QUARTER_RATE 21 -#define AR5K_INIT_SLOT_TIME_B 20 -#define AR5K_SLOT_TIME_MAX 0xffff - -/* SIFS */ -#define AR5K_INIT_SIFS_TURBO 6 -#define AR5K_INIT_SIFS_DEFAULT_BG 10 -#define AR5K_INIT_SIFS_DEFAULT_A 16 -#define AR5K_INIT_SIFS_HALF_RATE 32 -#define AR5K_INIT_SIFS_QUARTER_RATE 64 - -/* Used to calculate tx time for non 5/10/40MHz - * operation */ -/* It's preamble time + signal time (16 + 4) */ -#define AR5K_INIT_OFDM_PREAMPLE_TIME 20 -/* Preamble time for 40MHz (turbo) operation (min ?) */ -#define AR5K_INIT_OFDM_PREAMBLE_TIME_MIN 14 -#define AR5K_INIT_OFDM_SYMBOL_TIME 4 -#define AR5K_INIT_OFDM_PLCP_BITS 22 - -/* Rx latency for 5 and 10MHz operation (max ?) */ -#define AR5K_INIT_RX_LAT_MAX 63 -/* Tx latencies from initvals (5212 only but no problem - * because we only tweak them on 5212) */ -#define AR5K_INIT_TX_LAT_A 54 -#define AR5K_INIT_TX_LAT_BG 384 -/* Tx latency for 40MHz (turbo) operation (min ?) */ -#define AR5K_INIT_TX_LAT_MIN 32 -/* Default Tx/Rx latencies (same for 5211)*/ -#define AR5K_INIT_TX_LATENCY_5210 54 -#define AR5K_INIT_RX_LATENCY_5210 29 - -/* Tx frame to Tx data start delay */ -#define AR5K_INIT_TXF2TXD_START_DEFAULT 14 -#define AR5K_INIT_TXF2TXD_START_DELAY_10MHZ 12 -#define AR5K_INIT_TXF2TXD_START_DELAY_5MHZ 13 - -/* We need to increase PHY switch and agc settling time - * on turbo mode */ -#define AR5K_SWITCH_SETTLING 5760 -#define AR5K_SWITCH_SETTLING_TURBO 7168 - -#define AR5K_AGC_SETTLING 28 -/* 38 on 5210 but shouldn't matter */ -#define AR5K_AGC_SETTLING_TURBO 37 - - - -/*****************************\ -* GENERIC CHIPSET DEFINITIONS * -\*****************************/ - -/** - * enum ath5k_version - MAC Chips - * @AR5K_AR5210: AR5210 (Crete) - * @AR5K_AR5211: AR5211 (Oahu/Maui) - * @AR5K_AR5212: AR5212 (Venice) and newer - */ -enum ath5k_version { - AR5K_AR5210 = 0, - AR5K_AR5211 = 1, - AR5K_AR5212 = 2, -}; - -/** - * enum ath5k_radio - PHY Chips - * @AR5K_RF5110: RF5110 (Fez) - * @AR5K_RF5111: RF5111 (Sombrero) - * @AR5K_RF5112: RF2112/5112(A) (Derby/Derby2) - * @AR5K_RF2413: RF2413/2414 (Griffin/Griffin-Lite) - * @AR5K_RF5413: RF5413/5414/5424 (Eagle/Condor) - * @AR5K_RF2316: RF2315/2316 (Cobra SoC) - * @AR5K_RF2317: RF2317 (Spider SoC) - * @AR5K_RF2425: RF2425/2417 (Swan/Nalla) - */ -enum ath5k_radio { - AR5K_RF5110 = 0, - AR5K_RF5111 = 1, - AR5K_RF5112 = 2, - AR5K_RF2413 = 3, - AR5K_RF5413 = 4, - AR5K_RF2316 = 5, - AR5K_RF2317 = 6, - AR5K_RF2425 = 7, -}; - -/* - * Common silicon revision/version values - */ - -#define AR5K_SREV_UNKNOWN 0xffff - -#define AR5K_SREV_AR5210 0x00 /* Crete */ -#define AR5K_SREV_AR5311 0x10 /* Maui 1 */ -#define AR5K_SREV_AR5311A 0x20 /* Maui 2 */ -#define AR5K_SREV_AR5311B 0x30 /* Spirit */ -#define AR5K_SREV_AR5211 0x40 /* Oahu */ -#define AR5K_SREV_AR5212 0x50 /* Venice */ -#define AR5K_SREV_AR5312_R2 0x52 /* AP31 */ -#define AR5K_SREV_AR5212_V4 0x54 /* ??? */ -#define AR5K_SREV_AR5213 0x55 /* ??? */ -#define AR5K_SREV_AR5312_R7 0x57 /* AP30 */ -#define AR5K_SREV_AR2313_R8 0x58 /* AP43 */ -#define AR5K_SREV_AR5213A 0x59 /* Hainan */ -#define AR5K_SREV_AR2413 0x78 /* Griffin lite */ -#define AR5K_SREV_AR2414 0x70 /* Griffin */ -#define AR5K_SREV_AR2315_R6 0x86 /* AP51-Light */ -#define AR5K_SREV_AR2315_R7 0x87 /* AP51-Full */ -#define AR5K_SREV_AR5424 0x90 /* Condor */ -#define AR5K_SREV_AR2317_R1 0x90 /* AP61-Light */ -#define AR5K_SREV_AR2317_R2 0x91 /* AP61-Full */ -#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ -#define AR5K_SREV_AR5414 0xa0 /* Eagle */ -#define AR5K_SREV_AR2415 0xb0 /* Talon */ -#define AR5K_SREV_AR5416 0xc0 /* PCI-E */ -#define AR5K_SREV_AR5418 0xca /* PCI-E */ -#define AR5K_SREV_AR2425 0xe0 /* Swan */ -#define AR5K_SREV_AR2417 0xf0 /* Nala */ - -#define AR5K_SREV_RAD_5110 0x00 -#define AR5K_SREV_RAD_5111 0x10 -#define AR5K_SREV_RAD_5111A 0x15 -#define AR5K_SREV_RAD_2111 0x20 -#define AR5K_SREV_RAD_5112 0x30 -#define AR5K_SREV_RAD_5112A 0x35 -#define AR5K_SREV_RAD_5112B 0x36 -#define AR5K_SREV_RAD_2112 0x40 -#define AR5K_SREV_RAD_2112A 0x45 -#define AR5K_SREV_RAD_2112B 0x46 -#define AR5K_SREV_RAD_2413 0x50 -#define AR5K_SREV_RAD_5413 0x60 -#define AR5K_SREV_RAD_2316 0x70 /* Cobra SoC */ -#define AR5K_SREV_RAD_2317 0x80 -#define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ -#define AR5K_SREV_RAD_2425 0xa2 -#define AR5K_SREV_RAD_5133 0xc0 - -#define AR5K_SREV_PHY_5211 0x30 -#define AR5K_SREV_PHY_5212 0x41 -#define AR5K_SREV_PHY_5212A 0x42 -#define AR5K_SREV_PHY_5212B 0x43 -#define AR5K_SREV_PHY_2413 0x45 -#define AR5K_SREV_PHY_5413 0x61 -#define AR5K_SREV_PHY_2425 0x70 - -/* TODO add support to mac80211 for vendor-specific rates and modes */ - -/** - * DOC: Atheros XR - * - * Some of this information is based on Documentation from: - * - * http://madwifi-project.org/wiki/ChipsetFeatures/SuperAG - * - * Atheros' eXtended Range - range enhancing extension is a modulation scheme - * that is supposed to double the link distance between an Atheros XR-enabled - * client device with an Atheros XR-enabled access point. This is achieved - * by increasing the receiver sensitivity up to, -105dBm, which is about 20dB - * above what the 802.11 specifications demand. In addition, new (proprietary) - * data rates are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s. - * - * Please note that can you either use XR or TURBO but you cannot use both, - * they are exclusive. - * - * Also note that we do not plan to support XR mode at least for now. You can - * get a mode similar to XR by using 5MHz bwmode. - */ - - -/** - * DOC: Atheros SuperAG - * - * In addition to XR we have another modulation scheme called TURBO mode - * that is supposed to provide a throughput transmission speed up to 40Mbit/s - * -60Mbit/s at a 108Mbit/s signaling rate achieved through the bonding of two - * 54Mbit/s 802.11g channels. To use this feature both ends must support it. - * There is also a distinction between "static" and "dynamic" turbo modes: - * - * - Static: is the dumb version: devices set to this mode stick to it until - * the mode is turned off. - * - * - Dynamic: is the intelligent version, the network decides itself if it - * is ok to use turbo. As soon as traffic is detected on adjacent channels - * (which would get used in turbo mode), or when a non-turbo station joins - * the network, turbo mode won't be used until the situation changes again. - * Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which - * monitors the used radio band in order to decide whether turbo mode may - * be used or not. - * - * This article claims Super G sticks to bonding of channels 5 and 6 for - * USA: - * - * http://www.pcworld.com/article/id,113428-page,1/article.html - * - * The channel bonding seems to be driver specific though. - * - * In addition to TURBO modes we also have the following features for even - * greater speed-up: - * - * - Bursting: allows multiple frames to be sent at once, rather than pausing - * after each frame. Bursting is a standards-compliant feature that can be - * used with any Access Point. - * - * - Fast frames: increases the amount of information that can be sent per - * frame, also resulting in a reduction of transmission overhead. It is a - * proprietary feature that needs to be supported by the Access Point. - * - * - Compression: data frames are compressed in real time using a Lempel Ziv - * algorithm. This is done transparently. Once this feature is enabled, - * compression and decompression takes place inside the chipset, without - * putting additional load on the host CPU. - * - * As with XR we also don't plan to support SuperAG features for now. You can - * get a mode similar to TURBO by using 40MHz bwmode. - */ - - -/** - * enum ath5k_driver_mode - PHY operation mode - * @AR5K_MODE_11A: 802.11a - * @AR5K_MODE_11B: 802.11b - * @AR5K_MODE_11G: 801.11g - * @AR5K_MODE_MAX: Used for boundary checks - * - * Do not change the order here, we use these as - * array indices and it also maps EEPROM structures. - */ -enum ath5k_driver_mode { - AR5K_MODE_11A = 0, - AR5K_MODE_11B = 1, - AR5K_MODE_11G = 2, - AR5K_MODE_MAX = 3 -}; - -/** - * enum ath5k_ant_mode - Antenna operation mode - * @AR5K_ANTMODE_DEFAULT: Default antenna setup - * @AR5K_ANTMODE_FIXED_A: Only antenna A is present - * @AR5K_ANTMODE_FIXED_B: Only antenna B is present - * @AR5K_ANTMODE_SINGLE_AP: STA locked on a single ap - * @AR5K_ANTMODE_SECTOR_AP: AP with tx antenna set on tx desc - * @AR5K_ANTMODE_SECTOR_STA: STA with tx antenna set on tx desc - * @AR5K_ANTMODE_DEBUG: Debug mode -A -> Rx, B-> Tx- - * @AR5K_ANTMODE_MAX: Used for boundary checks - * - * For more infos on antenna control check out phy.c - */ -enum ath5k_ant_mode { - AR5K_ANTMODE_DEFAULT = 0, - AR5K_ANTMODE_FIXED_A = 1, - AR5K_ANTMODE_FIXED_B = 2, - AR5K_ANTMODE_SINGLE_AP = 3, - AR5K_ANTMODE_SECTOR_AP = 4, - AR5K_ANTMODE_SECTOR_STA = 5, - AR5K_ANTMODE_DEBUG = 6, - AR5K_ANTMODE_MAX, -}; - -/** - * enum ath5k_bw_mode - Bandwidth operation mode - * @AR5K_BWMODE_DEFAULT: 20MHz, default operation - * @AR5K_BWMODE_5MHZ: Quarter rate - * @AR5K_BWMODE_10MHZ: Half rate - * @AR5K_BWMODE_40MHZ: Turbo - */ -enum ath5k_bw_mode { - AR5K_BWMODE_DEFAULT = 0, - AR5K_BWMODE_5MHZ = 1, - AR5K_BWMODE_10MHZ = 2, - AR5K_BWMODE_40MHZ = 3 -}; - - - -/****************\ - TX DEFINITIONS -\****************/ - -/** - * struct ath5k_tx_status - TX Status descriptor - * @ts_seqnum: Sequence number - * @ts_tstamp: Timestamp - * @ts_status: Status code - * @ts_final_idx: Final transmission series index - * @ts_final_retry: Final retry count - * @ts_rssi: RSSI for received ACK - * @ts_shortretry: Short retry count - * @ts_virtcol: Virtual collision count - * @ts_antenna: Antenna used - * - * TX status descriptor gets filled by the hw - * on each transmission attempt. - */ -struct ath5k_tx_status { - u16 ts_seqnum; - u16 ts_tstamp; - u8 ts_status; - u8 ts_final_idx; - u8 ts_final_retry; - s8 ts_rssi; - u8 ts_shortretry; - u8 ts_virtcol; - u8 ts_antenna; -}; - -#define AR5K_TXSTAT_ALTRATE 0x80 -#define AR5K_TXERR_XRETRY 0x01 -#define AR5K_TXERR_FILT 0x02 -#define AR5K_TXERR_FIFO 0x04 - -/** - * enum ath5k_tx_queue - Queue types used to classify tx queues. - * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue - * @AR5K_TX_QUEUE_DATA: A normal data queue - * @AR5K_TX_QUEUE_BEACON: The beacon queue - * @AR5K_TX_QUEUE_CAB: The after-beacon queue - * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue - */ -enum ath5k_tx_queue { - AR5K_TX_QUEUE_INACTIVE = 0, - AR5K_TX_QUEUE_DATA, - AR5K_TX_QUEUE_BEACON, - AR5K_TX_QUEUE_CAB, - AR5K_TX_QUEUE_UAPSD, -}; - -#define AR5K_NUM_TX_QUEUES 10 -#define AR5K_NUM_TX_QUEUES_NOQCU 2 - -/** - * enum ath5k_tx_queue_subtype - Queue sub-types to classify normal data queues - * @AR5K_WME_AC_BK: Background traffic - * @AR5K_WME_AC_BE: Best-effort (normal) traffic - * @AR5K_WME_AC_VI: Video traffic - * @AR5K_WME_AC_VO: Voice traffic - * - * These are the 4 Access Categories as defined in - * WME spec. 0 is the lowest priority and 4 is the - * highest. Normal data that hasn't been classified - * goes to the Best Effort AC. - */ -enum ath5k_tx_queue_subtype { - AR5K_WME_AC_BK = 0, - AR5K_WME_AC_BE, - AR5K_WME_AC_VI, - AR5K_WME_AC_VO, -}; - -/** - * enum ath5k_tx_queue_id - Queue ID numbers as returned by the hw functions - * @AR5K_TX_QUEUE_ID_NOQCU_DATA: Data queue on AR5210 (no QCU available) - * @AR5K_TX_QUEUE_ID_NOQCU_BEACON: Beacon queue on AR5210 (no QCU available) - * @AR5K_TX_QUEUE_ID_DATA_MIN: Data queue min index - * @AR5K_TX_QUEUE_ID_DATA_MAX: Data queue max index - * @AR5K_TX_QUEUE_ID_CAB: Content after beacon queue - * @AR5K_TX_QUEUE_ID_BEACON: Beacon queue - * @AR5K_TX_QUEUE_ID_UAPSD: Urgent Automatic Power Save Delivery, - * - * Each number represents a hw queue. If hw does not support hw queues - * (eg 5210) all data goes in one queue. - */ -enum ath5k_tx_queue_id { - AR5K_TX_QUEUE_ID_NOQCU_DATA = 0, - AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1, - AR5K_TX_QUEUE_ID_DATA_MIN = 0, - AR5K_TX_QUEUE_ID_DATA_MAX = 3, - AR5K_TX_QUEUE_ID_UAPSD = 7, - AR5K_TX_QUEUE_ID_CAB = 8, - AR5K_TX_QUEUE_ID_BEACON = 9, -}; - -/* - * Flags to set hw queue's parameters... - */ -#define AR5K_TXQ_FLAG_TXOKINT_ENABLE 0x0001 /* Enable TXOK interrupt */ -#define AR5K_TXQ_FLAG_TXERRINT_ENABLE 0x0002 /* Enable TXERR interrupt */ -#define AR5K_TXQ_FLAG_TXEOLINT_ENABLE 0x0004 /* Enable TXEOL interrupt -not used- */ -#define AR5K_TXQ_FLAG_TXDESCINT_ENABLE 0x0008 /* Enable TXDESC interrupt -not used- */ -#define AR5K_TXQ_FLAG_TXURNINT_ENABLE 0x0010 /* Enable TXURN interrupt */ -#define AR5K_TXQ_FLAG_CBRORNINT_ENABLE 0x0020 /* Enable CBRORN interrupt */ -#define AR5K_TXQ_FLAG_CBRURNINT_ENABLE 0x0040 /* Enable CBRURN interrupt */ -#define AR5K_TXQ_FLAG_QTRIGINT_ENABLE 0x0080 /* Enable QTRIG interrupt */ -#define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE 0x0100 /* Enable TXNOFRM interrupt */ -#define AR5K_TXQ_FLAG_BACKOFF_DISABLE 0x0200 /* Disable random post-backoff */ -#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE 0x0300 /* Enable ready time expiry policy (?)*/ -#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE 0x0800 /* Enable backoff while bursting */ -#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS 0x1000 /* Disable backoff while bursting */ -#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE 0x2000 /* Enable hw compression -not implemented-*/ - -/** - * struct ath5k_txq - Transmit queue state - * @qnum: Hardware q number - * @link: Link ptr in last TX desc - * @q: Transmit queue (&struct list_head) - * @lock: Lock on q and link - * @setup: Is the queue configured - * @txq_len:Number of queued buffers - * @txq_max: Max allowed num of queued buffers - * @txq_poll_mark: Used to check if queue got stuck - * @txq_stuck: Queue stuck counter - * - * One of these exists for each hardware transmit queue. - * Packets sent to us from above are assigned to queues based - * on their priority. Not all devices support a complete set - * of hardware transmit queues. For those devices the array - * sc_ac2q will map multiple priorities to fewer hardware queues - * (typically all to one hardware queue). - */ -struct ath5k_txq { - unsigned int qnum; - u32 *link; - struct list_head q; - spinlock_t lock; - bool setup; - int txq_len; - int txq_max; - bool txq_poll_mark; - unsigned int txq_stuck; -}; - -/** - * struct ath5k_txq_info - A struct to hold TX queue's parameters - * @tqi_type: One of enum ath5k_tx_queue - * @tqi_subtype: One of enum ath5k_tx_queue_subtype - * @tqi_flags: TX queue flags (see above) - * @tqi_aifs: Arbitrated Inter-frame Space - * @tqi_cw_min: Minimum Contention Window - * @tqi_cw_max: Maximum Contention Window - * @tqi_cbr_period: Constant bit rate period - * @tqi_ready_time: Time queue waits after an event when RDYTIME is enabled - */ -struct ath5k_txq_info { - enum ath5k_tx_queue tqi_type; - enum ath5k_tx_queue_subtype tqi_subtype; - u16 tqi_flags; - u8 tqi_aifs; - u16 tqi_cw_min; - u16 tqi_cw_max; - u32 tqi_cbr_period; - u32 tqi_cbr_overflow_limit; - u32 tqi_burst_time; - u32 tqi_ready_time; -}; - -/** - * enum ath5k_pkt_type - Transmit packet types - * @AR5K_PKT_TYPE_NORMAL: Normal data - * @AR5K_PKT_TYPE_ATIM: ATIM - * @AR5K_PKT_TYPE_PSPOLL: PS-Poll - * @AR5K_PKT_TYPE_BEACON: Beacon - * @AR5K_PKT_TYPE_PROBE_RESP: Probe response - * @AR5K_PKT_TYPE_PIFS: PIFS - * Used on tx control descriptor - */ -enum ath5k_pkt_type { - AR5K_PKT_TYPE_NORMAL = 0, - AR5K_PKT_TYPE_ATIM = 1, - AR5K_PKT_TYPE_PSPOLL = 2, - AR5K_PKT_TYPE_BEACON = 3, - AR5K_PKT_TYPE_PROBE_RESP = 4, - AR5K_PKT_TYPE_PIFS = 5, -}; - -/* - * TX power and TPC settings - */ -#define AR5K_TXPOWER_OFDM(_r, _v) ( \ - ((0 & 1) << ((_v) + 6)) | \ - (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \ -) - -#define AR5K_TXPOWER_CCK(_r, _v) ( \ - (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v) \ -) - - - -/****************\ - RX DEFINITIONS -\****************/ - -/** - * struct ath5k_rx_status - RX Status descriptor - * @rs_datalen: Data length - * @rs_tstamp: Timestamp - * @rs_status: Status code - * @rs_phyerr: PHY error mask - * @rs_rssi: RSSI in 0.5dbm units - * @rs_keyix: Index to the key used for decrypting - * @rs_rate: Rate used to decode the frame - * @rs_antenna: Antenna used to receive the frame - * @rs_more: Indicates this is a frame fragment (Fast frames) - */ -struct ath5k_rx_status { - u16 rs_datalen; - u16 rs_tstamp; - u8 rs_status; - u8 rs_phyerr; - s8 rs_rssi; - u8 rs_keyix; - u8 rs_rate; - u8 rs_antenna; - u8 rs_more; -}; - -#define AR5K_RXERR_CRC 0x01 -#define AR5K_RXERR_PHY 0x02 -#define AR5K_RXERR_FIFO 0x04 -#define AR5K_RXERR_DECRYPT 0x08 -#define AR5K_RXERR_MIC 0x10 -#define AR5K_RXKEYIX_INVALID ((u8) -1) -#define AR5K_TXKEYIX_INVALID ((u32) -1) - - -/**************************\ - BEACON TIMERS DEFINITIONS -\**************************/ - -#define AR5K_BEACON_PERIOD 0x0000ffff -#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ -#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ - - -/* - * TSF to TU conversion: - * - * TSF is a 64bit value in usec (microseconds). - * TU is a 32bit value and defined by IEEE802.11 (page 6) as "A measurement of - * time equal to 1024 usec", so it's roughly milliseconds (usec / 1024). - */ -#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) - - - -/*******************************\ - GAIN OPTIMIZATION DEFINITIONS -\*******************************/ - -/** - * enum ath5k_rfgain - RF Gain optimization engine state - * @AR5K_RFGAIN_INACTIVE: Engine disabled - * @AR5K_RFGAIN_ACTIVE: Probe active - * @AR5K_RFGAIN_READ_REQUESTED: Probe requested - * @AR5K_RFGAIN_NEED_CHANGE: Gain_F needs change - */ -enum ath5k_rfgain { - AR5K_RFGAIN_INACTIVE = 0, - AR5K_RFGAIN_ACTIVE, - AR5K_RFGAIN_READ_REQUESTED, - AR5K_RFGAIN_NEED_CHANGE, -}; - -/** - * struct ath5k_gain - RF Gain optimization engine state data - * @g_step_idx: Current step index - * @g_current: Current gain - * @g_target: Target gain - * @g_low: Low gain boundary - * @g_high: High gain boundary - * @g_f_corr: Gain_F correction - * @g_state: One of enum ath5k_rfgain - */ -struct ath5k_gain { - u8 g_step_idx; - u8 g_current; - u8 g_target; - u8 g_low; - u8 g_high; - u8 g_f_corr; - u8 g_state; -}; - - - -/********************\ - COMMON DEFINITIONS -\********************/ - -#define AR5K_SLOT_TIME_9 396 -#define AR5K_SLOT_TIME_20 880 -#define AR5K_SLOT_TIME_MAX 0xffff - -/** - * struct ath5k_athchan_2ghz - 2GHz to 5GHZ map for RF5111 - * @a2_flags: Channel flags (internal) - * @a2_athchan: HW channel number (internal) - * - * This structure is used to map 2GHz channels to - * 5GHz Atheros channels on 2111 frequency converter - * that comes together with RF5111 - * TODO: Clean up - */ -struct ath5k_athchan_2ghz { - u32 a2_flags; - u16 a2_athchan; -}; - -/** - * enum ath5k_dmasize - DMA size definitions (2^(n+2)) - * @AR5K_DMASIZE_4B: 4Bytes - * @AR5K_DMASIZE_8B: 8Bytes - * @AR5K_DMASIZE_16B: 16Bytes - * @AR5K_DMASIZE_32B: 32Bytes - * @AR5K_DMASIZE_64B: 64Bytes (Default) - * @AR5K_DMASIZE_128B: 128Bytes - * @AR5K_DMASIZE_256B: 256Bytes - * @AR5K_DMASIZE_512B: 512Bytes - * - * These are used to set DMA burst size on hw - * - * Note: Some platforms can't handle more than 4Bytes - * be careful on embedded boards. - */ -enum ath5k_dmasize { - AR5K_DMASIZE_4B = 0, - AR5K_DMASIZE_8B, - AR5K_DMASIZE_16B, - AR5K_DMASIZE_32B, - AR5K_DMASIZE_64B, - AR5K_DMASIZE_128B, - AR5K_DMASIZE_256B, - AR5K_DMASIZE_512B -}; - - - -/******************\ - RATE DEFINITIONS -\******************/ - -/** - * DOC: Rate codes - * - * Seems the ar5xxx hardware supports up to 32 rates, indexed by 1-32. - * - * The rate code is used to get the RX rate or set the TX rate on the - * hardware descriptors. It is also used for internal modulation control - * and settings. - * - * This is the hardware rate map we are aware of (html unfriendly): - * - * Rate code Rate (Kbps) - * --------- ----------- - * 0x01 3000 (XR) - * 0x02 1000 (XR) - * 0x03 250 (XR) - * 0x04 - 05 -Reserved- - * 0x06 2000 (XR) - * 0x07 500 (XR) - * 0x08 48000 (OFDM) - * 0x09 24000 (OFDM) - * 0x0A 12000 (OFDM) - * 0x0B 6000 (OFDM) - * 0x0C 54000 (OFDM) - * 0x0D 36000 (OFDM) - * 0x0E 18000 (OFDM) - * 0x0F 9000 (OFDM) - * 0x10 - 17 -Reserved- - * 0x18 11000L (CCK) - * 0x19 5500L (CCK) - * 0x1A 2000L (CCK) - * 0x1B 1000L (CCK) - * 0x1C 11000S (CCK) - * 0x1D 5500S (CCK) - * 0x1E 2000S (CCK) - * 0x1F -Reserved- - * - * "S" indicates CCK rates with short preamble and "L" with long preamble. - * - * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the - * lowest 4 bits, so they are the same as above with a 0xF mask. - * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M). - * We handle this in ath5k_setup_bands(). - */ -#define AR5K_MAX_RATES 32 - -/* B */ -#define ATH5K_RATE_CODE_1M 0x1B -#define ATH5K_RATE_CODE_2M 0x1A -#define ATH5K_RATE_CODE_5_5M 0x19 -#define ATH5K_RATE_CODE_11M 0x18 -/* A and G */ -#define ATH5K_RATE_CODE_6M 0x0B -#define ATH5K_RATE_CODE_9M 0x0F -#define ATH5K_RATE_CODE_12M 0x0A -#define ATH5K_RATE_CODE_18M 0x0E -#define ATH5K_RATE_CODE_24M 0x09 -#define ATH5K_RATE_CODE_36M 0x0D -#define ATH5K_RATE_CODE_48M 0x08 -#define ATH5K_RATE_CODE_54M 0x0C - -/* Adding this flag to rate_code on B rates - * enables short preamble */ -#define AR5K_SET_SHORT_PREAMBLE 0x04 - -/* - * Crypto definitions - */ - -#define AR5K_KEYCACHE_SIZE 8 -extern bool ath5k_modparam_nohwcrypt; - -/***********************\ - HW RELATED DEFINITIONS -\***********************/ - -/* - * Misc definitions - */ -#define AR5K_RSSI_EP_MULTIPLIER (1 << 7) - -#define AR5K_ASSERT_ENTRY(_e, _s) do { \ - if (_e >= _s) \ - return false; \ -} while (0) - -/* - * Hardware interrupt abstraction - */ - -/** - * enum ath5k_int - Hardware interrupt masks helpers - * @AR5K_INT_RXOK: Frame successfully received - * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor - * @AR5K_INT_RXERR: Frame reception failed - * @AR5K_INT_RXNOFRM: No frame received within a specified time period - * @AR5K_INT_RXEOL: Reached "End Of List", means we need more RX descriptors - * @AR5K_INT_RXORN: Indicates we got RX FIFO overrun. Note that Rx overrun is - * not always fatal, on some chips we can continue operation - * without resetting the card, that's why %AR5K_INT_FATAL is not - * common for all chips. - * @AR5K_INT_RX_ALL: Mask to identify all RX related interrupts - * - * @AR5K_INT_TXOK: Frame transmission success - * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor - * @AR5K_INT_TXERR: Frame transmission failure - * @AR5K_INT_TXEOL: Received End Of List for VEOL (Virtual End Of List). The - * Queue Control Unit (QCU) signals an EOL interrupt only if a - * descriptor's LinkPtr is NULL. For more details, refer to: - * "http://www.freepatentsonline.com/20030225739.html" - * @AR5K_INT_TXNOFRM: No frame was transmitted within a specified time period - * @AR5K_INT_TXURN: Indicates we got TX FIFO underrun. In such case we should - * increase the TX trigger threshold. - * @AR5K_INT_TX_ALL: Mask to identify all TX related interrupts - * - * @AR5K_INT_MIB: Indicates the either Management Information Base counters or - * one of the PHY error counters reached the maximum value and - * should be read and cleared. - * @AR5K_INT_SWI: Software triggered interrupt. - * @AR5K_INT_RXPHY: RX PHY Error - * @AR5K_INT_RXKCM: RX Key cache miss - * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a - * beacon that must be handled in software. The alternative is if - * you have VEOL support, in that case you let the hardware deal - * with things. - * @AR5K_INT_BRSSI: Beacon received with an RSSI value below our threshold - * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing - * beacons from the AP have associated with, we should probably - * try to reassociate. When in IBSS mode this might mean we have - * not received any beacons from any local stations. Note that - * every station in an IBSS schedules to send beacons at the - * Target Beacon Transmission Time (TBTT) with a random backoff. - * @AR5K_INT_BNR: Beacon queue got triggered (DMA beacon alert) while empty. - * @AR5K_INT_TIM: Beacon with local station's TIM bit set - * @AR5K_INT_DTIM: Beacon with DTIM bit and zero DTIM count received - * @AR5K_INT_DTIM_SYNC: DTIM sync lost - * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill switches connected to - * our GPIO pins. - * @AR5K_INT_BCN_TIMEOUT: Beacon timeout, we waited after TBTT but got noting - * @AR5K_INT_CAB_TIMEOUT: We waited for CAB traffic after the beacon but got - * nothing or an incomplete CAB frame sequence. - * @AR5K_INT_QCBRORN: A queue got it's CBR counter expired - * @AR5K_INT_QCBRURN: A queue got triggered wile empty - * @AR5K_INT_QTRIG: A queue got triggered - * - * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by bus/DMA - * errors. Indicates we need to reset the card. - * @AR5K_INT_GLOBAL: Used to clear and set the IER - * @AR5K_INT_NOCARD: Signals the card has been removed - * @AR5K_INT_COMMON: Common interrupts shared among MACs with the same - * bit value - * - * These are mapped to take advantage of some common bits - * between the MACs, to be able to set intr properties - * easier. Some of them are not used yet inside hw.c. Most map - * to the respective hw interrupt value as they are common among different - * MACs. - */ -enum ath5k_int { - AR5K_INT_RXOK = 0x00000001, - AR5K_INT_RXDESC = 0x00000002, - AR5K_INT_RXERR = 0x00000004, - AR5K_INT_RXNOFRM = 0x00000008, - AR5K_INT_RXEOL = 0x00000010, - AR5K_INT_RXORN = 0x00000020, - AR5K_INT_TXOK = 0x00000040, - AR5K_INT_TXDESC = 0x00000080, - AR5K_INT_TXERR = 0x00000100, - AR5K_INT_TXNOFRM = 0x00000200, - AR5K_INT_TXEOL = 0x00000400, - AR5K_INT_TXURN = 0x00000800, - AR5K_INT_MIB = 0x00001000, - AR5K_INT_SWI = 0x00002000, - AR5K_INT_RXPHY = 0x00004000, - AR5K_INT_RXKCM = 0x00008000, - AR5K_INT_SWBA = 0x00010000, - AR5K_INT_BRSSI = 0x00020000, - AR5K_INT_BMISS = 0x00040000, - AR5K_INT_FATAL = 0x00080000, /* Non common */ - AR5K_INT_BNR = 0x00100000, /* Non common */ - AR5K_INT_TIM = 0x00200000, /* Non common */ - AR5K_INT_DTIM = 0x00400000, /* Non common */ - AR5K_INT_DTIM_SYNC = 0x00800000, /* Non common */ - AR5K_INT_GPIO = 0x01000000, - AR5K_INT_BCN_TIMEOUT = 0x02000000, /* Non common */ - AR5K_INT_CAB_TIMEOUT = 0x04000000, /* Non common */ - AR5K_INT_QCBRORN = 0x08000000, /* Non common */ - AR5K_INT_QCBRURN = 0x10000000, /* Non common */ - AR5K_INT_QTRIG = 0x20000000, /* Non common */ - AR5K_INT_GLOBAL = 0x80000000, - - AR5K_INT_TX_ALL = AR5K_INT_TXOK - | AR5K_INT_TXDESC - | AR5K_INT_TXERR - | AR5K_INT_TXNOFRM - | AR5K_INT_TXEOL - | AR5K_INT_TXURN, - - AR5K_INT_RX_ALL = AR5K_INT_RXOK - | AR5K_INT_RXDESC - | AR5K_INT_RXERR - | AR5K_INT_RXNOFRM - | AR5K_INT_RXEOL - | AR5K_INT_RXORN, - - AR5K_INT_COMMON = AR5K_INT_RXOK - | AR5K_INT_RXDESC - | AR5K_INT_RXERR - | AR5K_INT_RXNOFRM - | AR5K_INT_RXEOL - | AR5K_INT_RXORN - | AR5K_INT_TXOK - | AR5K_INT_TXDESC - | AR5K_INT_TXERR - | AR5K_INT_TXNOFRM - | AR5K_INT_TXEOL - | AR5K_INT_TXURN - | AR5K_INT_MIB - | AR5K_INT_SWI - | AR5K_INT_RXPHY - | AR5K_INT_RXKCM - | AR5K_INT_SWBA - | AR5K_INT_BRSSI - | AR5K_INT_BMISS - | AR5K_INT_GPIO - | AR5K_INT_GLOBAL, - - AR5K_INT_NOCARD = 0xffffffff -}; - -/** - * enum ath5k_calibration_mask - Mask which calibration is active at the moment - * @AR5K_CALIBRATION_FULL: Full calibration (AGC + SHORT) - * @AR5K_CALIBRATION_SHORT: Short calibration (NF + I/Q) - * @AR5K_CALIBRATION_NF: Noise Floor calibration - * @AR5K_CALIBRATION_ANI: Adaptive Noise Immunity - */ -enum ath5k_calibration_mask { - AR5K_CALIBRATION_FULL = 0x01, - AR5K_CALIBRATION_SHORT = 0x02, - AR5K_CALIBRATION_NF = 0x04, - AR5K_CALIBRATION_ANI = 0x08, -}; - -/** - * enum ath5k_power_mode - Power management modes - * @AR5K_PM_UNDEFINED: Undefined - * @AR5K_PM_AUTO: Allow card to sleep if possible - * @AR5K_PM_AWAKE: Force card to wake up - * @AR5K_PM_FULL_SLEEP: Force card to full sleep (DANGEROUS) - * @AR5K_PM_NETWORK_SLEEP: Allow to sleep for a specified duration - * - * Currently only PM_AWAKE is used, FULL_SLEEP and NETWORK_SLEEP/AUTO - * are also known to have problems on some cards. This is not a big - * problem though because we can have almost the same effect as - * FULL_SLEEP by putting card on warm reset (it's almost powered down). - */ -enum ath5k_power_mode { - AR5K_PM_UNDEFINED = 0, - AR5K_PM_AUTO, - AR5K_PM_AWAKE, - AR5K_PM_FULL_SLEEP, - AR5K_PM_NETWORK_SLEEP, -}; - -/* - * These match net80211 definitions (not used in - * mac80211). - * TODO: Clean this up - */ -#define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/ -#define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/ -#define AR5K_LED_AUTH 2 /*IEEE80211_S_AUTH*/ -#define AR5K_LED_ASSOC 3 /*IEEE80211_S_ASSOC*/ -#define AR5K_LED_RUN 4 /*IEEE80211_S_RUN*/ - -/* GPIO-controlled software LED */ -#define AR5K_SOFTLED_PIN 0 -#define AR5K_SOFTLED_ON 0 -#define AR5K_SOFTLED_OFF 1 - - -/* XXX: we *may* move cap_range stuff to struct wiphy */ -struct ath5k_capabilities { - /* - * Supported PHY modes - * (ie. AR5K_MODE_11A, AR5K_MODE_11B, ...) - */ - DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX); - - /* - * Frequency range (without regulation restrictions) - */ - struct { - u16 range_2ghz_min; - u16 range_2ghz_max; - u16 range_5ghz_min; - u16 range_5ghz_max; - } cap_range; - - /* - * Values stored in the EEPROM (some of them...) - */ - struct ath5k_eeprom_info cap_eeprom; - - /* - * Queue information - */ - struct { - u8 q_tx_num; - } cap_queues; - - bool cap_has_phyerr_counters; - bool cap_has_mrr_support; - bool cap_needs_2GHz_ovr; -}; - -/* size of noise floor history (keep it a power of two) */ -#define ATH5K_NF_CAL_HIST_MAX 8 -struct ath5k_nfcal_hist { - s16 index; /* current index into nfval */ - s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ -}; - -#define ATH5K_LED_MAX_NAME_LEN 31 - -/* - * State for LED triggers - */ -struct ath5k_led { - char name[ATH5K_LED_MAX_NAME_LEN + 1]; /* name of the LED in sysfs */ - struct ath5k_hw *ah; /* driver state */ - struct led_classdev led_dev; /* led classdev */ -}; - -/* Rfkill */ -struct ath5k_rfkill { - /* GPIO PIN for rfkill */ - u16 gpio; - /* polarity of rfkill GPIO PIN */ - bool polarity; - /* RFKILL toggle tasklet */ - struct tasklet_struct toggleq; -}; - -/* statistics */ -struct ath5k_statistics { - /* antenna use */ - unsigned int antenna_rx[5]; /* frames count per antenna RX */ - unsigned int antenna_tx[5]; /* frames count per antenna TX */ - - /* frame errors */ - unsigned int rx_all_count; /* all RX frames, including errors */ - unsigned int tx_all_count; /* all TX frames, including errors */ - unsigned int rx_bytes_count; /* all RX bytes, including errored pkts - * and the MAC headers for each packet - */ - unsigned int tx_bytes_count; /* all TX bytes, including errored pkts - * and the MAC headers and padding for - * each packet. - */ - unsigned int rxerr_crc; - unsigned int rxerr_phy; - unsigned int rxerr_phy_code[32]; - unsigned int rxerr_fifo; - unsigned int rxerr_decrypt; - unsigned int rxerr_mic; - unsigned int rxerr_proc; - unsigned int rxerr_jumbo; - unsigned int txerr_retry; - unsigned int txerr_fifo; - unsigned int txerr_filt; - - /* MIB counters */ - unsigned int ack_fail; - unsigned int rts_fail; - unsigned int rts_ok; - unsigned int fcs_error; - unsigned int beacons; - - unsigned int mib_intr; - unsigned int rxorn_intr; - unsigned int rxeol_intr; -}; - -/* - * Misc defines - */ - -#define AR5K_MAX_GPIO 10 -#define AR5K_MAX_RF_BANKS 8 - -#if CHAN_DEBUG -#define ATH_CHAN_MAX (26 + 26 + 26 + 200 + 200) -#else -#define ATH_CHAN_MAX (14 + 14 + 14 + 252 + 20) -#endif - -#define ATH_RXBUF 40 /* number of RX buffers */ -#define ATH_TXBUF 200 /* number of TX buffers */ -#define ATH_BCBUF 4 /* number of beacon buffers */ -#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ -#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ - -/* Driver state associated with an instance of a device */ -struct ath5k_hw { - struct ath_common common; - - struct pci_dev *pdev; - struct device *dev; /* for dma mapping */ - int irq; - u16 devid; - void __iomem *iobase; /* address of the device */ - struct mutex lock; /* dev-level lock */ - struct ieee80211_hw *hw; /* IEEE 802.11 common */ - struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; - struct ieee80211_channel channels[ATH_CHAN_MAX]; - struct ieee80211_rate rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES]; - s8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES]; - enum nl80211_iftype opmode; - -#ifdef CONFIG_ATH5K_DEBUG - struct ath5k_dbg_info debug; /* debug info */ -#endif /* CONFIG_ATH5K_DEBUG */ - - struct ath5k_buf *bufptr; /* allocated buffer ptr */ - struct ath5k_desc *desc; /* TX/RX descriptors */ - dma_addr_t desc_daddr; /* DMA (physical) address */ - size_t desc_len; /* size of TX/RX descriptors */ - - DECLARE_BITMAP(status, 4); -#define ATH_STAT_INVALID 0 /* disable hardware accesses */ -#define ATH_STAT_PROMISC 1 -#define ATH_STAT_LEDSOFT 2 /* enable LED gpio status */ -#define ATH_STAT_STARTED 3 /* opened & irqs enabled */ - - unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ - struct ieee80211_channel *curchan; /* current h/w channel */ - - u16 nvifs; - - enum ath5k_int imask; /* interrupt mask copy */ - - spinlock_t irqlock; - bool rx_pending; /* rx tasklet pending */ - bool tx_pending; /* tx tasklet pending */ - - u8 bssidmask[ETH_ALEN]; - - unsigned int led_pin, /* GPIO pin for driving LED */ - led_on; /* pin setting for LED on */ - - struct work_struct reset_work; /* deferred chip reset */ - struct work_struct calib_work; /* deferred phy calibration */ - - struct list_head rxbuf; /* receive buffer */ - spinlock_t rxbuflock; - u32 *rxlink; /* link ptr in last RX desc */ - struct tasklet_struct rxtq; /* rx intr tasklet */ - struct ath5k_led rx_led; /* rx led */ - - struct list_head txbuf; /* transmit buffer */ - spinlock_t txbuflock; - unsigned int txbuf_len; /* buf count in txbuf list */ - struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */ - struct tasklet_struct txtq; /* tx intr tasklet */ - struct ath5k_led tx_led; /* tx led */ - - struct ath5k_rfkill rf_kill; - - spinlock_t block; /* protects beacon */ - struct tasklet_struct beacontq; /* beacon intr tasklet */ - struct list_head bcbuf; /* beacon buffer */ - 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 */ - bsent; - unsigned int nexttbtt; /* next beacon time in TU */ - struct ath5k_txq *cabq; /* content after beacon */ - - int power_level; /* Requested tx power in dBm */ - bool assoc; /* associate state */ - bool enable_beacon; /* true if beacons are on */ - - struct ath5k_statistics stats; - - struct ath5k_ani_state ani_state; - struct tasklet_struct ani_tasklet; /* ANI calibration */ - - struct delayed_work tx_complete_work; - - struct survey_info survey; /* collected survey info */ - - enum ath5k_int ah_imr; - - struct ieee80211_channel *ah_current_channel; - bool ah_iq_cal_needed; - bool ah_single_chip; - - enum ath5k_version ah_version; - enum ath5k_radio ah_radio; - u32 ah_mac_srev; - u16 ah_mac_version; - u16 ah_phy_revision; - u16 ah_radio_5ghz_revision; - u16 ah_radio_2ghz_revision; - -#define ah_modes ah_capabilities.cap_mode -#define ah_ee_version ah_capabilities.cap_eeprom.ee_version - - u8 ah_retry_long; - u8 ah_retry_short; - - u32 ah_use_32khz_clock; - - u8 ah_coverage_class; - bool ah_ack_bitrate_high; - u8 ah_bwmode; - bool ah_short_slot; - - /* Antenna Control */ - u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; - u8 ah_ant_mode; - u8 ah_tx_ant; - u8 ah_def_ant; - - struct ath5k_capabilities ah_capabilities; - - struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; - u32 ah_txq_status; - u32 ah_txq_imr_txok; - u32 ah_txq_imr_txerr; - u32 ah_txq_imr_txurn; - u32 ah_txq_imr_txdesc; - u32 ah_txq_imr_txeol; - u32 ah_txq_imr_cbrorn; - u32 ah_txq_imr_cbrurn; - u32 ah_txq_imr_qtrig; - u32 ah_txq_imr_nofrm; - - u32 ah_txq_isr_txok_all; - u32 ah_txq_isr_txurn; - u32 ah_txq_isr_qcborn; - u32 ah_txq_isr_qcburn; - u32 ah_txq_isr_qtrig; - - u32 *ah_rf_banks; - size_t ah_rf_banks_size; - size_t ah_rf_regs_count; - struct ath5k_gain ah_gain; - u8 ah_offset[AR5K_MAX_RF_BANKS]; - - - struct { - /* Temporary tables used for interpolation */ - u8 tmpL[AR5K_EEPROM_N_PD_GAINS] - [AR5K_EEPROM_POWER_TABLE_SIZE]; - u8 tmpR[AR5K_EEPROM_N_PD_GAINS] - [AR5K_EEPROM_POWER_TABLE_SIZE]; - u8 txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2]; - u16 txp_rates_power_table[AR5K_MAX_RATES]; - u8 txp_min_idx; - bool txp_tpc; - /* Values in 0.25dB units */ - s16 txp_min_pwr; - s16 txp_max_pwr; - s16 txp_cur_pwr; - /* Values in 0.5dB units */ - s16 txp_offset; - s16 txp_ofdm; - s16 txp_cck_ofdm_gainf_delta; - /* Value in dB units */ - s16 txp_cck_ofdm_pwr_delta; - bool txp_setup; - } ah_txpower; - - struct ath5k_nfcal_hist ah_nfcal_hist; - - /* average beacon RSSI in our BSS (used by ANI) */ - struct ewma ah_beacon_rssi_avg; - - /* noise floor from last periodic calibration */ - s32 ah_noise_floor; - - /* Calibration timestamp */ - unsigned long ah_cal_next_full; - unsigned long ah_cal_next_short; - unsigned long ah_cal_next_ani; - - /* Calibration mask */ - u8 ah_cal_mask; - - /* - * Function pointers - */ - int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, - unsigned int, unsigned int, int, enum ath5k_pkt_type, - unsigned int, unsigned int, unsigned int, unsigned int, - unsigned int, unsigned int, unsigned int, unsigned int); - int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, - struct ath5k_tx_status *); - int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *, - struct ath5k_rx_status *); -}; - -struct ath_bus_ops { - enum ath_bus_type ath_bus_type; - void (*read_cachesize)(struct ath_common *common, int *csz); - bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); - int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac); -}; - -/* - * Prototypes - */ -extern const struct ieee80211_ops ath5k_hw_ops; - -/* Initialization and detach functions */ -int ath5k_hw_init(struct ath5k_hw *ah); -void ath5k_hw_deinit(struct ath5k_hw *ah); - -int ath5k_sysfs_register(struct ath5k_hw *ah); -void ath5k_sysfs_unregister(struct ath5k_hw *ah); - -/*Chip id helper functions */ -int ath5k_hw_read_srev(struct ath5k_hw *ah); - -/* LED functions */ -int ath5k_init_leds(struct ath5k_hw *ah); -void ath5k_led_enable(struct ath5k_hw *ah); -void ath5k_led_off(struct ath5k_hw *ah); -void ath5k_unregister_leds(struct ath5k_hw *ah); - - -/* Reset Functions */ -int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel); -int ath5k_hw_on_hold(struct ath5k_hw *ah); -int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, - struct ieee80211_channel *channel, bool fast, bool skip_pcu); -int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, - bool is_set); -/* Power management functions */ - - -/* Clock rate related functions */ -unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); -unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); -void ath5k_hw_set_clockrate(struct ath5k_hw *ah); - - -/* DMA Related Functions */ -void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); -u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); -int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); -int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); -int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue); -u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); -int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, - u32 phys_addr); -int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); -/* Interrupt handling */ -bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); -int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); -enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); -void ath5k_hw_update_mib_counters(struct ath5k_hw *ah); -/* Init/Stop functions */ -void ath5k_hw_dma_init(struct ath5k_hw *ah); -int ath5k_hw_dma_stop(struct ath5k_hw *ah); - -/* EEPROM access functions */ -int ath5k_eeprom_init(struct ath5k_hw *ah); -void ath5k_eeprom_detach(struct ath5k_hw *ah); - - -/* Protocol Control Unit Functions */ -/* Helpers */ -int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, - int len, struct ieee80211_rate *rate, bool shortpre); -unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); -unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); -int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); -void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); -/* RX filter control*/ -int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); -void ath5k_hw_set_bssid(struct ath5k_hw *ah); -void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); -void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); -u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); -void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); -/* Receive (DRU) start/stop functions */ -void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); -void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); -/* Beacon control functions */ -u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); -void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); -void ath5k_hw_reset_tsf(struct ath5k_hw *ah); -void ath5k_hw_init_beacon_timers(struct ath5k_hw *ah, u32 next_beacon, - u32 interval); -bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval); -/* Init function */ -void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode); - -/* Queue Control Unit, DFS Control Unit Functions */ -int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, - struct ath5k_txq_info *queue_info); -int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, - const struct ath5k_txq_info *queue_info); -int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, - enum ath5k_tx_queue queue_type, - struct ath5k_txq_info *queue_info); -void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, - unsigned int queue); -u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); -void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); -int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); -int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time); -/* Init function */ -int ath5k_hw_init_queues(struct ath5k_hw *ah); - -/* Hardware Descriptor Functions */ -int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); -int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, - u32 size, unsigned int flags); -int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, - unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, - u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3); - - -/* GPIO Functions */ -void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); -int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); -int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); -u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); -int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); -void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, - u32 interrupt_level); - - -/* RFkill Functions */ -void ath5k_rfkill_hw_start(struct ath5k_hw *ah); -void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); - - -/* Misc functions TODO: Cleanup */ -int ath5k_hw_set_capabilities(struct ath5k_hw *ah); -int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); -int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); - - -/* Initial register settings functions */ -int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); - - -/* PHY functions */ -/* Misc PHY functions */ -u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band); -int ath5k_hw_phy_disable(struct ath5k_hw *ah); -/* Gain_F optimization */ -enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); -int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); -/* PHY/RF channel functions */ -bool ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel); -/* PHY calibration */ -void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); -int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, - struct ieee80211_channel *channel); -void ath5k_hw_update_noise_floor(struct ath5k_hw *ah); -/* Spur mitigation */ -bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, - struct ieee80211_channel *channel); -/* Antenna control */ -void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); -void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode); -/* TX power setup */ -int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); -/* Init function */ -int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, bool fast); - -/* - * Functions used internally - */ - -static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) -{ - return &ah->common; -} - -static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) -{ - return &(ath5k_hw_common(ah)->regulatory); -} - -#ifdef CONFIG_ATHEROS_AR231X -#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000) - -static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) -{ - /* On AR2315 and AR2317 the PCI clock domain registers - * are outside of the WMAC register space */ - if (unlikely((reg >= 0x4000) && (reg < 0x5000) && - (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) - return AR5K_AR2315_PCI_BASE + reg; - - return ah->iobase + reg; -} - -static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) -{ - return ioread32(ath5k_ahb_reg(ah, reg)); -} - -static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) -{ - iowrite32(val, ath5k_ahb_reg(ah, reg)); -} - -#else - -static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) -{ - return ioread32(ah->iobase + reg); -} - -static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) -{ - iowrite32(val, ah->iobase + reg); -} - -#endif - -static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) -{ - return ath5k_hw_common(ah)->bus_ops->ath_bus_type; -} - -static inline void ath5k_read_cachesize(struct ath_common *common, int *csz) -{ - common->bus_ops->read_cachesize(common, csz); -} - -static inline bool ath5k_hw_nvram_read(struct ath5k_hw *ah, u32 off, u16 *data) -{ - struct ath_common *common = ath5k_hw_common(ah); - return common->bus_ops->eeprom_read(common, off, data); -} - -static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) -{ - u32 retval = 0, bit, i; - - for (i = 0; i < bits; i++) { - bit = (val >> i) & 1; - retval = (retval << 1) | bit; - } - - return retval; -} - -#endif diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/attach.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/attach.c deleted file mode 100644 index d7114c75..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/attach.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/*************************************\ -* Attach/Detach Functions and helpers * -\*************************************/ - -#include <linux/pci.h> -#include <linux/slab.h> -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - -/** - * ath5k_hw_post() - Power On Self Test helper function - * @ah: The &struct ath5k_hw - */ -static int ath5k_hw_post(struct ath5k_hw *ah) -{ - - static const u32 static_pattern[4] = { - 0x55555555, 0xaaaaaaaa, - 0x66666666, 0x99999999 - }; - static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) }; - int i, c; - u16 cur_reg; - u32 var_pattern; - u32 init_val; - u32 cur_val; - - for (c = 0; c < 2; c++) { - - cur_reg = regs[c]; - - /* Save previous value */ - init_val = ath5k_hw_reg_read(ah, cur_reg); - - for (i = 0; i < 256; i++) { - var_pattern = i << 16 | i; - ath5k_hw_reg_write(ah, var_pattern, cur_reg); - cur_val = ath5k_hw_reg_read(ah, cur_reg); - - if (cur_val != var_pattern) { - ATH5K_ERR(ah, "POST Failed !!!\n"); - return -EAGAIN; - } - - /* Found on ndiswrapper dumps */ - var_pattern = 0x0039080f; - ath5k_hw_reg_write(ah, var_pattern, cur_reg); - } - - for (i = 0; i < 4; i++) { - var_pattern = static_pattern[i]; - ath5k_hw_reg_write(ah, var_pattern, cur_reg); - cur_val = ath5k_hw_reg_read(ah, cur_reg); - - if (cur_val != var_pattern) { - ATH5K_ERR(ah, "POST Failed !!!\n"); - return -EAGAIN; - } - - /* Found on ndiswrapper dumps */ - var_pattern = 0x003b080f; - ath5k_hw_reg_write(ah, var_pattern, cur_reg); - } - - /* Restore previous value */ - ath5k_hw_reg_write(ah, init_val, cur_reg); - - } - - return 0; - -} - -/** - * ath5k_hw_init() - Check if hw is supported and init the needed structs - * @ah: The &struct ath5k_hw associated with the device - * - * Check if the device is supported, perform a POST and initialize the needed - * structs. Returns -ENOMEM if we don't have memory for the needed structs, - * -ENODEV if the device is not supported or prints an error msg if something - * else went wrong. - */ -int ath5k_hw_init(struct ath5k_hw *ah) -{ - static const u8 zero_mac[ETH_ALEN] = { }; - struct ath_common *common = ath5k_hw_common(ah); - struct pci_dev *pdev = ah->pdev; - struct ath5k_eeprom_info *ee; - int ret; - u32 srev; - - /* - * HW information - */ - ah->ah_bwmode = AR5K_BWMODE_DEFAULT; - ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; - ah->ah_imr = 0; - ah->ah_retry_short = AR5K_INIT_RETRY_SHORT; - ah->ah_retry_long = AR5K_INIT_RETRY_LONG; - ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; - ah->ah_noise_floor = -95; /* until first NF calibration is run */ - ah->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; - ah->ah_current_channel = &ah->channels[0]; - - /* - * Find the mac version - */ - ath5k_hw_read_srev(ah); - srev = ah->ah_mac_srev; - if (srev < AR5K_SREV_AR5311) - ah->ah_version = AR5K_AR5210; - else if (srev < AR5K_SREV_AR5212) - ah->ah_version = AR5K_AR5211; - else - ah->ah_version = AR5K_AR5212; - - /* Get the MAC version */ - ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); - - /* Fill the ath5k_hw struct with the needed functions */ - ret = ath5k_hw_init_desc_functions(ah); - if (ret) - goto err; - - /* Bring device out of sleep and reset its units */ - ret = ath5k_hw_nic_wakeup(ah, NULL); - if (ret) - goto err; - - /* Get PHY and RADIO revisions */ - ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & - 0xffffffff; - ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, - IEEE80211_BAND_5GHZ); - - /* Try to identify radio chip based on its srev */ - switch (ah->ah_radio_5ghz_revision & 0xf0) { - case AR5K_SREV_RAD_5111: - ah->ah_radio = AR5K_RF5111; - ah->ah_single_chip = false; - ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, - IEEE80211_BAND_2GHZ); - break; - case AR5K_SREV_RAD_5112: - case AR5K_SREV_RAD_2112: - ah->ah_radio = AR5K_RF5112; - ah->ah_single_chip = false; - ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, - IEEE80211_BAND_2GHZ); - break; - case AR5K_SREV_RAD_2413: - ah->ah_radio = AR5K_RF2413; - ah->ah_single_chip = true; - break; - case AR5K_SREV_RAD_5413: - ah->ah_radio = AR5K_RF5413; - ah->ah_single_chip = true; - break; - case AR5K_SREV_RAD_2316: - ah->ah_radio = AR5K_RF2316; - ah->ah_single_chip = true; - break; - case AR5K_SREV_RAD_2317: - ah->ah_radio = AR5K_RF2317; - ah->ah_single_chip = true; - break; - case AR5K_SREV_RAD_5424: - if (ah->ah_mac_version == AR5K_SREV_AR2425 || - ah->ah_mac_version == AR5K_SREV_AR2417) { - ah->ah_radio = AR5K_RF2425; - ah->ah_single_chip = true; - } else { - ah->ah_radio = AR5K_RF5413; - ah->ah_single_chip = true; - } - break; - default: - /* Identify radio based on mac/phy srev */ - if (ah->ah_version == AR5K_AR5210) { - ah->ah_radio = AR5K_RF5110; - ah->ah_single_chip = false; - } else if (ah->ah_version == AR5K_AR5211) { - ah->ah_radio = AR5K_RF5111; - ah->ah_single_chip = false; - ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, - IEEE80211_BAND_2GHZ); - } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || - ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || - ah->ah_phy_revision == AR5K_SREV_PHY_2425) { - ah->ah_radio = AR5K_RF2425; - ah->ah_single_chip = true; - ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; - } else if (srev == AR5K_SREV_AR5213A && - ah->ah_phy_revision == AR5K_SREV_PHY_5212B) { - ah->ah_radio = AR5K_RF5112; - ah->ah_single_chip = false; - ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; - } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) || - ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) { - ah->ah_radio = AR5K_RF2316; - ah->ah_single_chip = true; - ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; - } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || - ah->ah_phy_revision == AR5K_SREV_PHY_5413) { - ah->ah_radio = AR5K_RF5413; - ah->ah_single_chip = true; - ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; - } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || - ah->ah_phy_revision == AR5K_SREV_PHY_2413) { - ah->ah_radio = AR5K_RF2413; - ah->ah_single_chip = true; - ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; - } else { - ATH5K_ERR(ah, "Couldn't identify radio revision.\n"); - ret = -ENODEV; - goto err; - } - } - - - /* Return on unsupported chips (unsupported eeprom etc) */ - if ((srev >= AR5K_SREV_AR5416) && (srev < AR5K_SREV_AR2425)) { - ATH5K_ERR(ah, "Device not yet supported.\n"); - ret = -ENODEV; - goto err; - } - - /* - * POST - */ - ret = ath5k_hw_post(ah); - if (ret) - goto err; - - /* Enable pci core retry fix on Hainan (5213A) and later chips */ - if (srev >= AR5K_SREV_AR5213A) - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX); - - /* - * Get card capabilities, calibration values etc - * TODO: EEPROM work - */ - ret = ath5k_eeprom_init(ah); - if (ret) { - ATH5K_ERR(ah, "unable to init EEPROM\n"); - goto err; - } - - ee = &ah->ah_capabilities.cap_eeprom; - - /* - * Write PCI-E power save settings - */ - if ((ah->ah_version == AR5K_AR5212) && pdev && (pci_is_pcie(pdev))) { - ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); - ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); - - /* Shut off RX when elecidle is asserted */ - ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES); - ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES); - - /* If serdes programming is enabled, increase PCI-E - * tx power for systems with long trace from host - * to minicard connector. */ - if (ee->ee_serdes) - ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES); - else - ath5k_hw_reg_write(ah, 0xf6800579, AR5K_PCIE_SERDES); - - /* Shut off PLL and CLKREQ active in L1 */ - ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES); - - /* Preserve other settings */ - ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES); - ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES); - ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES); - - /* Reset SERDES to load new settings */ - ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET); - usleep_range(1000, 1500); - } - - /* Get misc capabilities */ - ret = ath5k_hw_set_capabilities(ah); - if (ret) { - ATH5K_ERR(ah, "unable to get device capabilities\n"); - goto err; - } - - /* Crypto settings */ - common->keymax = (ah->ah_version == AR5K_AR5210 ? - AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); - - if (srev >= AR5K_SREV_AR5212_V4 && - (ee->ee_version < AR5K_EEPROM_VERSION_5_0 || - !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) - common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; - - if (srev >= AR5K_SREV_AR2414) { - common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; - AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, - AR5K_MISC_MODE_COMBINED_MIC); - } - - /* MAC address is cleared until add_interface */ - ath5k_hw_set_lladdr(ah, zero_mac); - - /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ - memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); - ath5k_hw_set_bssid(ah); - ath5k_hw_set_opmode(ah, ah->opmode); - - ath5k_hw_rfgain_opt_init(ah); - - ath5k_hw_init_nfcal_hist(ah); - - /* turn on HW LEDs */ - ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); - - return 0; -err: - return ret; -} - -/** - * ath5k_hw_deinit() - Free the &struct ath5k_hw - * @ah: The &struct ath5k_hw - */ -void ath5k_hw_deinit(struct ath5k_hw *ah) -{ - __set_bit(ATH_STAT_INVALID, ah->status); - - if (ah->ah_rf_banks != NULL) - kfree(ah->ah_rf_banks); - - ath5k_eeprom_detach(ah); - - /* assume interrupts are down */ -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/base.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/base.c deleted file mode 100644 index 0e643b01..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/base.c +++ /dev/null @@ -1,3040 +0,0 @@ -/*- - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2004-2005 Atheros Communications, Inc. - * Copyright (c) 2006 Devicescape Software, Inc. - * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - * - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/hardirq.h> -#include <linux/if.h> -#include <linux/io.h> -#include <linux/netdevice.h> -#include <linux/cache.h> -#include <linux/ethtool.h> -#include <linux/uaccess.h> -#include <linux/slab.h> -#include <linux/etherdevice.h> -#include <linux/nl80211.h> - -#include <net/ieee80211_radiotap.h> - -#include <asm/unaligned.h> - -#include "base.h" -#include "reg.h" -#include "debug.h" -#include "ani.h" -#include "ath5k.h" -#include "../regd.h" - -#define CREATE_TRACE_POINTS -#include "trace.h" - -bool ath5k_modparam_nohwcrypt; -module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); -MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); - -static bool modparam_all_channels; -module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); -MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); - -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 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"); - - -/* Module info */ -MODULE_AUTHOR("Jiri Slaby"); -MODULE_AUTHOR("Nick Kossifidis"); -MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); -MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); -MODULE_LICENSE("Dual BSD/GPL"); - -static int ath5k_init(struct ieee80211_hw *hw); -static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, - bool skip_pcu); - -/* Known SREVs */ -static const struct ath5k_srev_name srev_names[] = { -#ifdef CONFIG_ATHEROS_AR231X - { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, - { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, - { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, - { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 }, - { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 }, - { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 }, - { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 }, -#else - { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, - { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, - { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, - { "5311B", AR5K_VERSION_MAC, AR5K_SREV_AR5311B }, - { "5211", AR5K_VERSION_MAC, AR5K_SREV_AR5211 }, - { "5212", AR5K_VERSION_MAC, AR5K_SREV_AR5212 }, - { "5213", AR5K_VERSION_MAC, AR5K_SREV_AR5213 }, - { "5213A", AR5K_VERSION_MAC, AR5K_SREV_AR5213A }, - { "2413", AR5K_VERSION_MAC, AR5K_SREV_AR2413 }, - { "2414", AR5K_VERSION_MAC, AR5K_SREV_AR2414 }, - { "5424", AR5K_VERSION_MAC, AR5K_SREV_AR5424 }, - { "5413", AR5K_VERSION_MAC, AR5K_SREV_AR5413 }, - { "5414", AR5K_VERSION_MAC, AR5K_SREV_AR5414 }, - { "2415", AR5K_VERSION_MAC, AR5K_SREV_AR2415 }, - { "5416", AR5K_VERSION_MAC, AR5K_SREV_AR5416 }, - { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, - { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, - { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, -#endif - { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, - { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, - { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, - { "5111A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111A }, - { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, - { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, - { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, - { "5112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112B }, - { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, - { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, - { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, - { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, - { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, - { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, - { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, -#ifdef CONFIG_ATHEROS_AR231X - { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, - { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, -#endif - { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, -}; - -static const struct ieee80211_rate ath5k_rates[] = { - { .bitrate = 10, - .hw_value = ATH5K_RATE_CODE_1M, }, - { .bitrate = 20, - .hw_value = ATH5K_RATE_CODE_2M, - .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, - .hw_value = ATH5K_RATE_CODE_5_5M, - .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, - .hw_value = ATH5K_RATE_CODE_11M, - .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE, - .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60, - .hw_value = ATH5K_RATE_CODE_6M, - .flags = 0 }, - { .bitrate = 90, - .hw_value = ATH5K_RATE_CODE_9M, - .flags = 0 }, - { .bitrate = 120, - .hw_value = ATH5K_RATE_CODE_12M, - .flags = 0 }, - { .bitrate = 180, - .hw_value = ATH5K_RATE_CODE_18M, - .flags = 0 }, - { .bitrate = 240, - .hw_value = ATH5K_RATE_CODE_24M, - .flags = 0 }, - { .bitrate = 360, - .hw_value = ATH5K_RATE_CODE_36M, - .flags = 0 }, - { .bitrate = 480, - .hw_value = ATH5K_RATE_CODE_48M, - .flags = 0 }, - { .bitrate = 540, - .hw_value = ATH5K_RATE_CODE_54M, - .flags = 0 }, -}; - -static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) -{ - u64 tsf = ath5k_hw_get_tsf64(ah); - - if ((tsf & 0x7fff) < rstamp) - tsf -= 0x8000; - - return (tsf & ~0x7fff) | rstamp; -} - -const char * -ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) -{ - const char *name = "xxxxx"; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(srev_names); i++) { - if (srev_names[i].sr_type != type) - continue; - - if ((val & 0xf0) == srev_names[i].sr_val) - name = srev_names[i].sr_name; - - if ((val & 0xff) == srev_names[i].sr_val) { - name = srev_names[i].sr_name; - break; - } - } - - return name; -} -static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset) -{ - struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv; - return ath5k_hw_reg_read(ah, reg_offset); -} - -static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) -{ - struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv; - ath5k_hw_reg_write(ah, val, reg_offset); -} - -static const struct ath_ops ath5k_common_ops = { - .read = ath5k_ioread32, - .write = ath5k_iowrite32, -}; - -/***********************\ -* Driver Initialization * -\***********************/ - -static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) -{ - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath5k_hw *ah = hw->priv; - struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); - - return ath_reg_notifier_apply(wiphy, request, regulatory); -} - -/********************\ -* Channel/mode setup * -\********************/ - -/* - * Returns true for the channel numbers used without all_channels modparam. - */ -static bool ath5k_is_standard_channel(short chan, enum ieee80211_band band) -{ - if (band == IEEE80211_BAND_2GHZ && chan <= 14) - return true; - - return /* UNII 1,2 */ - (((chan & 3) == 0 && chan >= 36 && chan <= 64) || - /* midband */ - ((chan & 3) == 0 && chan >= 100 && chan <= 140) || - /* UNII-3 */ - ((chan & 3) == 1 && chan >= 149 && chan <= 165) || - /* 802.11j 5.030-5.080 GHz (20MHz) */ - (chan == 8 || chan == 12 || chan == 16) || - /* 802.11j 4.9GHz (20MHz) */ - (chan == 184 || chan == 188 || chan == 192 || chan == 196)); -} - -static unsigned int -ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels, - unsigned int mode, unsigned int max) -{ - unsigned int count, size, freq, ch; - enum ieee80211_band band; - - switch (mode) { - case AR5K_MODE_11A: - /* 1..220, but 2GHz frequencies are filtered by check_channel */ - size = 220; - band = IEEE80211_BAND_5GHZ; - break; - case AR5K_MODE_11B: - case AR5K_MODE_11G: - size = 26; - band = IEEE80211_BAND_2GHZ; - break; - default: - ATH5K_WARN(ah, "bad mode, not copying channels\n"); - return 0; - } - - count = 0; - for (ch = 1; ch <= size && count < max; ch++) { - freq = ieee80211_channel_to_frequency(ch, band); - - if (freq == 0) /* mapping failed - not a standard channel */ - continue; - - /* Write channel info, needed for ath5k_channel_ok() */ - channels[count].center_freq = freq; - channels[count].band = band; - channels[count].hw_value = mode; - - /* Check if channel is supported by the chipset */ - if (!ath5k_channel_ok(ah, &channels[count])) - continue; - - if (!modparam_all_channels && - !ath5k_is_standard_channel(ch, band)) - continue; - - count++; - } - - return count; -} - -static void -ath5k_setup_rate_idx(struct ath5k_hw *ah, struct ieee80211_supported_band *b) -{ - u8 i; - - for (i = 0; i < AR5K_MAX_RATES; i++) - ah->rate_idx[b->band][i] = -1; - - for (i = 0; i < b->n_bitrates; i++) { - ah->rate_idx[b->band][b->bitrates[i].hw_value] = i; - if (b->bitrates[i].hw_value_short) - ah->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; - } -} - -static int -ath5k_setup_bands(struct ieee80211_hw *hw) -{ - struct ath5k_hw *ah = hw->priv; - struct ieee80211_supported_band *sband; - int max_c, count_c = 0; - int i; - - BUILD_BUG_ON(ARRAY_SIZE(ah->sbands) < IEEE80211_NUM_BANDS); - max_c = ARRAY_SIZE(ah->channels); - - /* 2GHz band */ - sband = &ah->sbands[IEEE80211_BAND_2GHZ]; - sband->band = IEEE80211_BAND_2GHZ; - sband->bitrates = &ah->rates[IEEE80211_BAND_2GHZ][0]; - - if (test_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode)) { - /* G mode */ - memcpy(sband->bitrates, &ath5k_rates[0], - sizeof(struct ieee80211_rate) * 12); - sband->n_bitrates = 12; - - sband->channels = ah->channels; - sband->n_channels = ath5k_setup_channels(ah, sband->channels, - AR5K_MODE_11G, max_c); - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; - count_c = sband->n_channels; - max_c -= count_c; - } else if (test_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode)) { - /* B mode */ - memcpy(sband->bitrates, &ath5k_rates[0], - sizeof(struct ieee80211_rate) * 4); - sband->n_bitrates = 4; - - /* 5211 only supports B rates and uses 4bit rate codes - * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) - * fix them up here: - */ - if (ah->ah_version == AR5K_AR5211) { - for (i = 0; i < 4; i++) { - sband->bitrates[i].hw_value = - sband->bitrates[i].hw_value & 0xF; - sband->bitrates[i].hw_value_short = - sband->bitrates[i].hw_value_short & 0xF; - } - } - - sband->channels = ah->channels; - sband->n_channels = ath5k_setup_channels(ah, sband->channels, - AR5K_MODE_11B, max_c); - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; - count_c = sband->n_channels; - max_c -= count_c; - } - ath5k_setup_rate_idx(ah, sband); - - /* 5GHz band, A mode */ - if (test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) { - sband = &ah->sbands[IEEE80211_BAND_5GHZ]; - sband->band = IEEE80211_BAND_5GHZ; - sband->bitrates = &ah->rates[IEEE80211_BAND_5GHZ][0]; - - memcpy(sband->bitrates, &ath5k_rates[4], - sizeof(struct ieee80211_rate) * 8); - sband->n_bitrates = 8; - - sband->channels = &ah->channels[count_c]; - sband->n_channels = ath5k_setup_channels(ah, sband->channels, - AR5K_MODE_11A, max_c); - - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; - } - ath5k_setup_rate_idx(ah, sband); - - ath5k_debug_dump_bands(ah); - - return 0; -} - -/* - * Set/change channels. We always reset the chip. - * To accomplish this we must first cleanup any pending DMA, - * then restart stuff after a la ath5k_init. - * - * Called with ah->lock. - */ -int -ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan) -{ - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "channel set, resetting (%u -> %u MHz)\n", - ah->curchan->center_freq, chan->center_freq); - - /* - * To switch channels clear any pending DMA operations; - * wait long enough for the RX fifo to drain, reset the - * hardware at the new frequency, and then re-enable - * the relevant bits of the h/w. - */ - return ath5k_reset(ah, chan, true); -} - -void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) -{ - struct ath5k_vif_iter_data *iter_data = data; - int i; - struct ath5k_vif *avf = (void *)vif->drv_priv; - - if (iter_data->hw_macaddr) - for (i = 0; i < ETH_ALEN; i++) - iter_data->mask[i] &= - ~(iter_data->hw_macaddr[i] ^ mac[i]); - - if (!iter_data->found_active) { - iter_data->found_active = true; - memcpy(iter_data->active_mac, mac, ETH_ALEN); - } - - if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) - if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) - iter_data->need_set_hw_addr = false; - - if (!iter_data->any_assoc) { - if (avf->assoc) - iter_data->any_assoc = true; - } - - /* Calculate combined mode - when APs are active, operate in AP mode. - * Otherwise use the mode of the new interface. This can currently - * only deal with combinations of APs and STAs. Only one ad-hoc - * interfaces is allowed. - */ - if (avf->opmode == NL80211_IFTYPE_AP) - iter_data->opmode = NL80211_IFTYPE_AP; - else { - if (avf->opmode == NL80211_IFTYPE_STATION) - iter_data->n_stas++; - if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) - iter_data->opmode = avf->opmode; - } -} - -void -ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah, - struct ieee80211_vif *vif) -{ - struct ath_common *common = ath5k_hw_common(ah); - struct ath5k_vif_iter_data iter_data; - u32 rfilt; - - /* - * Use the hardware MAC address as reference, the hardware uses it - * together with the BSSID mask when matching addresses. - */ - iter_data.hw_macaddr = common->macaddr; - memset(&iter_data.mask, 0xff, ETH_ALEN); - iter_data.found_active = false; - iter_data.need_set_hw_addr = true; - iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; - iter_data.n_stas = 0; - - if (vif) - ath5k_vif_iter(&iter_data, vif->addr, vif); - - /* Get list of all active MAC addresses */ - ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, - &iter_data); - memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN); - - ah->opmode = iter_data.opmode; - if (ah->opmode == NL80211_IFTYPE_UNSPECIFIED) - /* Nothing active, default to station mode */ - ah->opmode = NL80211_IFTYPE_STATION; - - ath5k_hw_set_opmode(ah, ah->opmode); - ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", - ah->opmode, ath_opmode_to_string(ah->opmode)); - - if (iter_data.need_set_hw_addr && iter_data.found_active) - ath5k_hw_set_lladdr(ah, iter_data.active_mac); - - if (ath5k_hw_hasbssidmask(ah)) - ath5k_hw_set_bssid_mask(ah, ah->bssidmask); - - /* Set up RX Filter */ - if (iter_data.n_stas > 1) { - /* If you have multiple STA interfaces connected to - * different APs, ARPs are not received (most of the time?) - * Enabling PROMISC appears to fix that problem. - */ - ah->filter_flags |= AR5K_RX_FILTER_PROM; - } - - rfilt = ah->filter_flags; - ath5k_hw_set_rx_filter(ah, rfilt); - ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); -} - -static inline int -ath5k_hw_to_driver_rix(struct ath5k_hw *ah, int hw_rix) -{ - int rix; - - /* return base rate on errors */ - if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES, - "hw_rix out of bounds: %x\n", hw_rix)) - return 0; - - rix = ah->rate_idx[ah->curchan->band][hw_rix]; - if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) - rix = 0; - - return rix; -} - -/***************\ -* Buffers setup * -\***************/ - -static -struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_hw *ah, dma_addr_t *skb_addr) -{ - struct ath_common *common = ath5k_hw_common(ah); - struct sk_buff *skb; - - /* - * Allocate buffer with headroom_needed space for the - * fake physical layer header at the start. - */ - skb = ath_rxbuf_alloc(common, - common->rx_bufsize, - GFP_ATOMIC); - - if (!skb) { - ATH5K_ERR(ah, "can't alloc skbuff of size %u\n", - common->rx_bufsize); - return NULL; - } - - *skb_addr = dma_map_single(ah->dev, - skb->data, common->rx_bufsize, - DMA_FROM_DEVICE); - - if (unlikely(dma_mapping_error(ah->dev, *skb_addr))) { - ATH5K_ERR(ah, "%s: DMA mapping failed\n", __func__); - dev_kfree_skb(skb); - return NULL; - } - return skb; -} - -static int -ath5k_rxbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf) -{ - struct sk_buff *skb = bf->skb; - struct ath5k_desc *ds; - int ret; - - if (!skb) { - skb = ath5k_rx_skb_alloc(ah, &bf->skbaddr); - if (!skb) - return -ENOMEM; - bf->skb = skb; - } - - /* - * Setup descriptors. For receive we always terminate - * the descriptor list with a self-linked entry so we'll - * not get overrun under high load (as can happen with a - * 5212 when ANI processing enables PHY error frames). - * - * To ensure the last descriptor is self-linked we create - * each descriptor as self-linked and add it to the end. As - * each additional descriptor is added the previous self-linked - * entry is "fixed" naturally. This should be safe even - * if DMA is happening. When processing RX interrupts we - * never remove/process the last, self-linked, entry on the - * descriptor list. This ensures the hardware always has - * someplace to write a new frame. - */ - ds = bf->desc; - ds->ds_link = bf->daddr; /* link to self */ - ds->ds_data = bf->skbaddr; - ret = ath5k_hw_setup_rx_desc(ah, ds, ah->common.rx_bufsize, 0); - if (ret) { - ATH5K_ERR(ah, "%s: could not setup RX desc\n", __func__); - return ret; - } - - if (ah->rxlink != NULL) - *ah->rxlink = bf->daddr; - ah->rxlink = &ds->ds_link; - return 0; -} - -static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - enum ath5k_pkt_type htype; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; - - if (ieee80211_is_beacon(fc)) - htype = AR5K_PKT_TYPE_BEACON; - else if (ieee80211_is_probe_resp(fc)) - htype = AR5K_PKT_TYPE_PROBE_RESP; - else if (ieee80211_is_atim(fc)) - htype = AR5K_PKT_TYPE_ATIM; - else if (ieee80211_is_pspoll(fc)) - htype = AR5K_PKT_TYPE_PSPOLL; - else - htype = AR5K_PKT_TYPE_NORMAL; - - return htype; -} - -static int -ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf, - struct ath5k_txq *txq, int padsize) -{ - struct ath5k_desc *ds = bf->desc; - struct sk_buff *skb = bf->skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; - struct ieee80211_rate *rate; - unsigned int mrr_rate[3], mrr_tries[3]; - int i, ret; - u16 hw_rate; - u16 cts_rate = 0; - u16 duration = 0; - u8 rc_flags; - - flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; - - /* XXX endianness */ - bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len, - DMA_TO_DEVICE); - - rate = ieee80211_get_tx_rate(ah->hw, info); - if (!rate) { - ret = -EINVAL; - goto err_unmap; - } - - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - flags |= AR5K_TXDESC_NOACK; - - rc_flags = info->control.rates[0].flags; - hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? - rate->hw_value_short : rate->hw_value; - - pktlen = skb->len; - - /* FIXME: If we are in g mode and rate is a CCK rate - * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta - * from tx power (value is in dB units already) */ - if (info->control.hw_key) { - keyidx = info->control.hw_key->hw_key_idx; - pktlen += info->control.hw_key->icv_len; - } - if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { - flags |= AR5K_TXDESC_RTSENA; - cts_rate = ieee80211_get_rts_cts_rate(ah->hw, info)->hw_value; - duration = le16_to_cpu(ieee80211_rts_duration(ah->hw, - info->control.vif, pktlen, info)); - } - if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - flags |= AR5K_TXDESC_CTSENA; - cts_rate = ieee80211_get_rts_cts_rate(ah->hw, info)->hw_value; - duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw, - info->control.vif, pktlen, info)); - } - ret = ah->ah_setup_tx_desc(ah, ds, pktlen, - ieee80211_get_hdrlen_from_skb(skb), padsize, - get_hw_packet_type(skb), - (ah->power_level * 2), - hw_rate, - info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, - cts_rate, duration); - if (ret) - goto err_unmap; - - /* Set up MRR descriptor */ - if (ah->ah_capabilities.cap_has_mrr_support) { - memset(mrr_rate, 0, sizeof(mrr_rate)); - memset(mrr_tries, 0, sizeof(mrr_tries)); - for (i = 0; i < 3; i++) { - rate = ieee80211_get_alt_retry_rate(ah->hw, info, i); - if (!rate) - break; - - mrr_rate[i] = rate->hw_value; - mrr_tries[i] = info->control.rates[i + 1].count; - } - - ath5k_hw_setup_mrr_tx_desc(ah, ds, - mrr_rate[0], mrr_tries[0], - mrr_rate[1], mrr_tries[1], - mrr_rate[2], mrr_tries[2]); - } - - ds->ds_link = 0; - ds->ds_data = bf->skbaddr; - - spin_lock_bh(&txq->lock); - list_add_tail(&bf->list, &txq->q); - txq->txq_len++; - if (txq->link == NULL) /* is this first packet? */ - ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); - else /* no, so only link it */ - *txq->link = bf->daddr; - - txq->link = &ds->ds_link; - ath5k_hw_start_tx_dma(ah, txq->qnum); - mmiowb(); - spin_unlock_bh(&txq->lock); - - return 0; -err_unmap: - dma_unmap_single(ah->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); - return ret; -} - -/*******************\ -* Descriptors setup * -\*******************/ - -static int -ath5k_desc_alloc(struct ath5k_hw *ah) -{ - struct ath5k_desc *ds; - struct ath5k_buf *bf; - dma_addr_t da; - unsigned int i; - int ret; - - /* allocate descriptors */ - ah->desc_len = sizeof(struct ath5k_desc) * - (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); - - ah->desc = dma_alloc_coherent(ah->dev, ah->desc_len, - &ah->desc_daddr, GFP_KERNEL); - if (ah->desc == NULL) { - ATH5K_ERR(ah, "can't allocate descriptors\n"); - ret = -ENOMEM; - goto err; - } - ds = ah->desc; - da = ah->desc_daddr; - ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n", - ds, ah->desc_len, (unsigned long long)ah->desc_daddr); - - bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF, - sizeof(struct ath5k_buf), GFP_KERNEL); - if (bf == NULL) { - ATH5K_ERR(ah, "can't allocate bufptr\n"); - ret = -ENOMEM; - goto err_free; - } - ah->bufptr = bf; - - INIT_LIST_HEAD(&ah->rxbuf); - for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) { - bf->desc = ds; - bf->daddr = da; - list_add_tail(&bf->list, &ah->rxbuf); - } - - INIT_LIST_HEAD(&ah->txbuf); - ah->txbuf_len = ATH_TXBUF; - for (i = 0; i < ATH_TXBUF; i++, bf++, ds++, da += sizeof(*ds)) { - bf->desc = ds; - bf->daddr = da; - list_add_tail(&bf->list, &ah->txbuf); - } - - /* beacon buffers */ - INIT_LIST_HEAD(&ah->bcbuf); - for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { - bf->desc = ds; - bf->daddr = da; - list_add_tail(&bf->list, &ah->bcbuf); - } - - return 0; -err_free: - dma_free_coherent(ah->dev, ah->desc_len, ah->desc, ah->desc_daddr); -err: - ah->desc = NULL; - return ret; -} - -void -ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf) -{ - BUG_ON(!bf); - if (!bf->skb) - return; - dma_unmap_single(ah->dev, bf->skbaddr, bf->skb->len, - DMA_TO_DEVICE); - dev_kfree_skb_any(bf->skb); - bf->skb = NULL; - bf->skbaddr = 0; - bf->desc->ds_data = 0; -} - -void -ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf) -{ - struct ath_common *common = ath5k_hw_common(ah); - - BUG_ON(!bf); - if (!bf->skb) - return; - dma_unmap_single(ah->dev, bf->skbaddr, common->rx_bufsize, - DMA_FROM_DEVICE); - dev_kfree_skb_any(bf->skb); - bf->skb = NULL; - bf->skbaddr = 0; - bf->desc->ds_data = 0; -} - -static void -ath5k_desc_free(struct ath5k_hw *ah) -{ - struct ath5k_buf *bf; - - list_for_each_entry(bf, &ah->txbuf, list) - ath5k_txbuf_free_skb(ah, bf); - list_for_each_entry(bf, &ah->rxbuf, list) - ath5k_rxbuf_free_skb(ah, bf); - list_for_each_entry(bf, &ah->bcbuf, list) - ath5k_txbuf_free_skb(ah, bf); - - /* Free memory associated with all descriptors */ - dma_free_coherent(ah->dev, ah->desc_len, ah->desc, ah->desc_daddr); - ah->desc = NULL; - ah->desc_daddr = 0; - - kfree(ah->bufptr); - ah->bufptr = NULL; -} - - -/**************\ -* Queues setup * -\**************/ - -static struct ath5k_txq * -ath5k_txq_setup(struct ath5k_hw *ah, - int qtype, int subtype) -{ - struct ath5k_txq *txq; - struct ath5k_txq_info qi = { - .tqi_subtype = subtype, - /* XXX: default values not correct for B and XR channels, - * but who cares? */ - .tqi_aifs = AR5K_TUNE_AIFS, - .tqi_cw_min = AR5K_TUNE_CWMIN, - .tqi_cw_max = AR5K_TUNE_CWMAX - }; - int qnum; - - /* - * Enable interrupts only for EOL and DESC conditions. - * We mark tx descriptors to receive a DESC interrupt - * when a tx queue gets deep; otherwise we wait for the - * EOL to reap descriptors. Note that this is done to - * reduce interrupt load and this only defers reaping - * descriptors, never transmitting frames. Aside from - * reducing interrupts this also permits more concurrency. - * The only potential downside is if the tx queue backs - * up in which case the top half of the kernel may backup - * due to a lack of tx descriptors. - */ - qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE | - AR5K_TXQ_FLAG_TXDESCINT_ENABLE; - qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi); - if (qnum < 0) { - /* - * NB: don't print a message, this happens - * normally on parts with too few tx queues - */ - return ERR_PTR(qnum); - } - txq = &ah->txqs[qnum]; - if (!txq->setup) { - txq->qnum = qnum; - txq->link = NULL; - INIT_LIST_HEAD(&txq->q); - spin_lock_init(&txq->lock); - txq->setup = true; - txq->txq_len = 0; - txq->txq_max = ATH5K_TXQ_LEN_MAX; - txq->txq_poll_mark = false; - txq->txq_stuck = 0; - } - return &ah->txqs[qnum]; -} - -static int -ath5k_beaconq_setup(struct ath5k_hw *ah) -{ - struct ath5k_txq_info qi = { - /* XXX: default values not correct for B and XR channels, - * but who cares? */ - .tqi_aifs = AR5K_TUNE_AIFS, - .tqi_cw_min = AR5K_TUNE_CWMIN, - .tqi_cw_max = AR5K_TUNE_CWMAX, - /* NB: for dynamic turbo, don't enable any other interrupts */ - .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE - }; - - return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi); -} - -static int -ath5k_beaconq_config(struct ath5k_hw *ah) -{ - struct ath5k_txq_info qi; - int ret; - - ret = ath5k_hw_get_tx_queueprops(ah, ah->bhalq, &qi); - if (ret) - goto err; - - if (ah->opmode == NL80211_IFTYPE_AP || - ah->opmode == NL80211_IFTYPE_MESH_POINT) { - /* - * Always burst out beacon and CAB traffic - * (aifs = cwmin = cwmax = 0) - */ - qi.tqi_aifs = 0; - qi.tqi_cw_min = 0; - qi.tqi_cw_max = 0; - } else if (ah->opmode == NL80211_IFTYPE_ADHOC) { - /* - * Adhoc mode; backoff between 0 and (2 * cw_min). - */ - qi.tqi_aifs = 0; - qi.tqi_cw_min = 0; - qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN; - } - - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, - "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", - qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); - - ret = ath5k_hw_set_tx_queueprops(ah, ah->bhalq, &qi); - if (ret) { - ATH5K_ERR(ah, "%s: unable to update parameters for beacon " - "hardware queue!\n", __func__); - goto err; - } - ret = ath5k_hw_reset_tx_queue(ah, ah->bhalq); /* push to h/w */ - if (ret) - goto err; - - /* reconfigure cabq with ready time to 80% of beacon_interval */ - ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); - if (ret) - goto err; - - qi.tqi_ready_time = (ah->bintval * 80) / 100; - ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); - if (ret) - goto err; - - ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); -err: - return ret; -} - -/** - * ath5k_drain_tx_buffs - Empty tx buffers - * - * @ah The &struct ath5k_hw - * - * Empty tx buffers from all queues in preparation - * of a reset or during shutdown. - * - * NB: this assumes output has been stopped and - * we do not need to block ath5k_tx_tasklet - */ -static void -ath5k_drain_tx_buffs(struct ath5k_hw *ah) -{ - struct ath5k_txq *txq; - struct ath5k_buf *bf, *bf0; - int i; - - for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) { - if (ah->txqs[i].setup) { - txq = &ah->txqs[i]; - spin_lock_bh(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ath5k_debug_printtxbuf(ah, bf); - - ath5k_txbuf_free_skb(ah, bf); - - spin_lock_bh(&ah->txbuflock); - list_move_tail(&bf->list, &ah->txbuf); - ah->txbuf_len++; - txq->txq_len--; - spin_unlock_bh(&ah->txbuflock); - } - txq->link = NULL; - txq->txq_poll_mark = false; - spin_unlock_bh(&txq->lock); - } - } -} - -static void -ath5k_txq_release(struct ath5k_hw *ah) -{ - struct ath5k_txq *txq = ah->txqs; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(ah->txqs); i++, txq++) - if (txq->setup) { - ath5k_hw_release_tx_queue(ah, txq->qnum); - txq->setup = false; - } -} - - -/*************\ -* RX Handling * -\*************/ - -/* - * Enable the receive h/w following a reset. - */ -static int -ath5k_rx_start(struct ath5k_hw *ah) -{ - struct ath_common *common = ath5k_hw_common(ah); - struct ath5k_buf *bf; - int ret; - - common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); - - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", - common->cachelsz, common->rx_bufsize); - - spin_lock_bh(&ah->rxbuflock); - ah->rxlink = NULL; - list_for_each_entry(bf, &ah->rxbuf, list) { - ret = ath5k_rxbuf_setup(ah, bf); - if (ret != 0) { - spin_unlock_bh(&ah->rxbuflock); - goto err; - } - } - bf = list_first_entry(&ah->rxbuf, struct ath5k_buf, list); - ath5k_hw_set_rxdp(ah, bf->daddr); - spin_unlock_bh(&ah->rxbuflock); - - ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ - ath5k_update_bssid_mask_and_opmode(ah, NULL); /* set filters, etc. */ - ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ - - return 0; -err: - return ret; -} - -/* - * Disable the receive logic on PCU (DRU) - * In preparation for a shutdown. - * - * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop - * does. - */ -static void -ath5k_rx_stop(struct ath5k_hw *ah) -{ - - ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ - ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ - - ath5k_debug_printrxbuffs(ah); -} - -static unsigned int -ath5k_rx_decrypted(struct ath5k_hw *ah, struct sk_buff *skb, - struct ath5k_rx_status *rs) -{ - struct ath_common *common = ath5k_hw_common(ah); - struct ieee80211_hdr *hdr = (void *)skb->data; - unsigned int keyix, hlen; - - if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && - rs->rs_keyix != AR5K_RXKEYIX_INVALID) - return RX_FLAG_DECRYPTED; - - /* Apparently when a default key is used to decrypt the packet - the hw does not set the index used to decrypt. In such cases - get the index from the packet. */ - hlen = ieee80211_hdrlen(hdr->frame_control); - if (ieee80211_has_protected(hdr->frame_control) && - !(rs->rs_status & AR5K_RXERR_DECRYPT) && - skb->len >= hlen + 4) { - keyix = skb->data[hlen + 3] >> 6; - - if (test_bit(keyix, common->keymap)) - return RX_FLAG_DECRYPTED; - } - - return 0; -} - - -static void -ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb, - struct ieee80211_rx_status *rxs) -{ - struct ath_common *common = ath5k_hw_common(ah); - u64 tsf, bc_tstamp; - u32 hw_tu; - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - - if (ieee80211_is_beacon(mgmt->frame_control) && - le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && - memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) { - /* - * Received an IBSS beacon with the same BSSID. Hardware *must* - * have updated the local TSF. We have to work around various - * hardware bugs, though... - */ - tsf = ath5k_hw_get_tsf64(ah); - bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp); - hw_tu = TSF_TO_TU(tsf); - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "beacon %llx mactime %llx (diff %lld) tsf now %llx\n", - (unsigned long long)bc_tstamp, - (unsigned long long)rxs->mactime, - (unsigned long long)(rxs->mactime - bc_tstamp), - (unsigned long long)tsf); - - /* - * Sometimes the HW will give us a wrong tstamp in the rx - * status, causing the timestamp extension to go wrong. - * (This seems to happen especially with beacon frames bigger - * than 78 byte (incl. FCS)) - * But we know that the receive timestamp must be later than the - * timestamp of the beacon since HW must have synced to that. - * - * NOTE: here we assume mactime to be after the frame was - * received, not like mac80211 which defines it at the start. - */ - if (bc_tstamp > rxs->mactime) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "fixing mactime from %llx to %llx\n", - (unsigned long long)rxs->mactime, - (unsigned long long)tsf); - rxs->mactime = tsf; - } - - /* - * Local TSF might have moved higher than our beacon timers, - * in that case we have to update them to continue sending - * beacons. This also takes care of synchronizing beacon sending - * times with other stations. - */ - if (hw_tu >= ah->nexttbtt) - ath5k_beacon_update_timers(ah, bc_tstamp); - - /* Check if the beacon timers are still correct, because a TSF - * update might have created a window between them - for a - * longer description see the comment of this function: */ - if (!ath5k_hw_check_beacon_timers(ah, ah->bintval)) { - ath5k_beacon_update_timers(ah, bc_tstamp); - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "fixed beacon timers after beacon receive\n"); - } - } -} - -static void -ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi) -{ - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - struct ath_common *common = ath5k_hw_common(ah); - - /* only beacons from our BSSID */ - if (!ieee80211_is_beacon(mgmt->frame_control) || - memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) - return; - - ewma_add(&ah->ah_beacon_rssi_avg, rssi); - - /* in IBSS mode we should keep RSSI statistics per neighbour */ - /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ -} - -/* - * Compute padding position. skb must contain an IEEE 802.11 frame - */ -static int ath5k_common_padpos(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - __le16 frame_control = hdr->frame_control; - int padpos = 24; - - if (ieee80211_has_a4(frame_control)) - padpos += ETH_ALEN; - - if (ieee80211_is_data_qos(frame_control)) - padpos += IEEE80211_QOS_CTL_LEN; - - return padpos; -} - -/* - * This function expects an 802.11 frame and returns the number of - * bytes added, or -1 if we don't have enough header room. - */ -static int ath5k_add_padding(struct sk_buff *skb) -{ - int padpos = ath5k_common_padpos(skb); - int padsize = padpos & 3; - - if (padsize && skb->len > padpos) { - - if (skb_headroom(skb) < padsize) - return -1; - - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, padpos); - return padsize; - } - - return 0; -} - -/* - * The MAC header is padded to have 32-bit boundary if the - * packet payload is non-zero. The general calculation for - * padsize would take into account odd header lengths: - * padsize = 4 - (hdrlen & 3); however, since only - * even-length headers are used, padding can only be 0 or 2 - * bytes and we can optimize this a bit. We must not try to - * remove padding from short control frames that do not have a - * payload. - * - * This function expects an 802.11 frame and returns the number of - * bytes removed. - */ -static int ath5k_remove_padding(struct sk_buff *skb) -{ - int padpos = ath5k_common_padpos(skb); - int padsize = padpos & 3; - - if (padsize && skb->len >= padpos + padsize) { - memmove(skb->data + padsize, skb->data, padpos); - skb_pull(skb, padsize); - return padsize; - } - - return 0; -} - -static void -ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb, - struct ath5k_rx_status *rs) -{ - struct ieee80211_rx_status *rxs; - - ath5k_remove_padding(skb); - - rxs = IEEE80211_SKB_RXCB(skb); - - rxs->flag = 0; - if (unlikely(rs->rs_status & AR5K_RXERR_MIC)) - rxs->flag |= RX_FLAG_MMIC_ERROR; - - /* - * always extend the mac timestamp, since this information is - * also needed for proper IBSS merging. - * - * XXX: it might be too late to do it here, since rs_tstamp is - * 15bit only. that means TSF extension has to be done within - * 32768usec (about 32ms). it might be necessary to move this to - * the interrupt handler, like it is done in madwifi. - * - * Unfortunately we don't know when the hardware takes the rx - * timestamp (beginning of phy frame, data frame, end of rx?). - * The only thing we know is that it is hardware specific... - * On AR5213 it seems the rx timestamp is at the end of the - * frame, but I'm not sure. - * - * NOTE: mac80211 defines mactime at the beginning of the first - * data symbol. Since we don't have any time references it's - * impossible to comply to that. This affects IBSS merge only - * right now, so it's not too bad... - */ - rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp); - rxs->flag |= RX_FLAG_MACTIME_MPDU; - - rxs->freq = ah->curchan->center_freq; - rxs->band = ah->curchan->band; - - rxs->signal = ah->ah_noise_floor + rs->rs_rssi; - - rxs->antenna = rs->rs_antenna; - - if (rs->rs_antenna > 0 && rs->rs_antenna < 5) - ah->stats.antenna_rx[rs->rs_antenna]++; - else - ah->stats.antenna_rx[0]++; /* invalid */ - - rxs->rate_idx = ath5k_hw_to_driver_rix(ah, rs->rs_rate); - rxs->flag |= ath5k_rx_decrypted(ah, skb, rs); - - if (rxs->rate_idx >= 0 && rs->rs_rate == - ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short) - rxs->flag |= RX_FLAG_SHORTPRE; - - trace_ath5k_rx(ah, skb); - - ath5k_update_beacon_rssi(ah, skb, rs->rs_rssi); - - /* check beacons in IBSS mode */ - if (ah->opmode == NL80211_IFTYPE_ADHOC) - ath5k_check_ibss_tsf(ah, skb, rxs); - - ieee80211_rx(ah->hw, skb); -} - -/** ath5k_frame_receive_ok() - Do we want to receive this frame or not? - * - * Check if we want to further process this frame or not. Also update - * statistics. Return true if we want this frame, false if not. - */ -static bool -ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs) -{ - ah->stats.rx_all_count++; - ah->stats.rx_bytes_count += rs->rs_datalen; - - if (unlikely(rs->rs_status)) { - if (rs->rs_status & AR5K_RXERR_CRC) - ah->stats.rxerr_crc++; - if (rs->rs_status & AR5K_RXERR_FIFO) - ah->stats.rxerr_fifo++; - if (rs->rs_status & AR5K_RXERR_PHY) { - ah->stats.rxerr_phy++; - if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32) - ah->stats.rxerr_phy_code[rs->rs_phyerr]++; - return false; - } - if (rs->rs_status & AR5K_RXERR_DECRYPT) { - /* - * Decrypt error. If the error occurred - * because there was no hardware key, then - * let the frame through so the upper layers - * can process it. This is necessary for 5210 - * parts which have no way to setup a ``clear'' - * key cache entry. - * - * XXX do key cache faulting - */ - ah->stats.rxerr_decrypt++; - if (rs->rs_keyix == AR5K_RXKEYIX_INVALID && - !(rs->rs_status & AR5K_RXERR_CRC)) - return true; - } - if (rs->rs_status & AR5K_RXERR_MIC) { - ah->stats.rxerr_mic++; - return true; - } - - /* reject any frames with non-crypto errors */ - if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) - return false; - } - - if (unlikely(rs->rs_more)) { - ah->stats.rxerr_jumbo++; - return false; - } - return true; -} - -static void -ath5k_set_current_imask(struct ath5k_hw *ah) -{ - enum ath5k_int imask; - unsigned long flags; - - spin_lock_irqsave(&ah->irqlock, flags); - imask = ah->imask; - if (ah->rx_pending) - imask &= ~AR5K_INT_RX_ALL; - if (ah->tx_pending) - imask &= ~AR5K_INT_TX_ALL; - ath5k_hw_set_imr(ah, imask); - spin_unlock_irqrestore(&ah->irqlock, flags); -} - -static void -ath5k_tasklet_rx(unsigned long data) -{ - struct ath5k_rx_status rs = {}; - struct sk_buff *skb, *next_skb; - dma_addr_t next_skb_addr; - struct ath5k_hw *ah = (void *)data; - struct ath_common *common = ath5k_hw_common(ah); - struct ath5k_buf *bf; - struct ath5k_desc *ds; - int ret; - - spin_lock(&ah->rxbuflock); - if (list_empty(&ah->rxbuf)) { - ATH5K_WARN(ah, "empty rx buf pool\n"); - goto unlock; - } - do { - bf = list_first_entry(&ah->rxbuf, struct ath5k_buf, list); - BUG_ON(bf->skb == NULL); - skb = bf->skb; - ds = bf->desc; - - /* bail if HW is still using self-linked descriptor */ - if (ath5k_hw_get_rxdp(ah) == bf->daddr) - break; - - ret = ah->ah_proc_rx_desc(ah, ds, &rs); - if (unlikely(ret == -EINPROGRESS)) - break; - else if (unlikely(ret)) { - ATH5K_ERR(ah, "error in processing rx descriptor\n"); - ah->stats.rxerr_proc++; - break; - } - - if (ath5k_receive_frame_ok(ah, &rs)) { - next_skb = ath5k_rx_skb_alloc(ah, &next_skb_addr); - - /* - * If we can't replace bf->skb with a new skb under - * memory pressure, just skip this packet - */ - if (!next_skb) - goto next; - - dma_unmap_single(ah->dev, bf->skbaddr, - common->rx_bufsize, - DMA_FROM_DEVICE); - - skb_put(skb, rs.rs_datalen); - - ath5k_receive_frame(ah, skb, &rs); - - bf->skb = next_skb; - bf->skbaddr = next_skb_addr; - } -next: - list_move_tail(&bf->list, &ah->rxbuf); - } while (ath5k_rxbuf_setup(ah, bf) == 0); -unlock: - spin_unlock(&ah->rxbuflock); - ah->rx_pending = false; - ath5k_set_current_imask(ah); -} - - -/*************\ -* TX Handling * -\*************/ - -void -ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq) -{ - struct ath5k_hw *ah = hw->priv; - struct ath5k_buf *bf; - unsigned long flags; - int padsize; - - trace_ath5k_tx(ah, skb, txq); - - /* - * The hardware expects the header padded to 4 byte boundaries. - * If this is not the case, we add the padding after the header. - */ - padsize = ath5k_add_padding(skb); - if (padsize < 0) { - ATH5K_ERR(ah, "tx hdrlen not %%4: not enough" - " headroom to pad"); - goto drop_packet; - } - - if (txq->txq_len >= txq->txq_max && - txq->qnum <= AR5K_TX_QUEUE_ID_DATA_MAX) - ieee80211_stop_queue(hw, txq->qnum); - - spin_lock_irqsave(&ah->txbuflock, flags); - if (list_empty(&ah->txbuf)) { - ATH5K_ERR(ah, "no further txbuf available, dropping packet\n"); - spin_unlock_irqrestore(&ah->txbuflock, flags); - ieee80211_stop_queues(hw); - goto drop_packet; - } - bf = list_first_entry(&ah->txbuf, struct ath5k_buf, list); - list_del(&bf->list); - ah->txbuf_len--; - if (list_empty(&ah->txbuf)) - ieee80211_stop_queues(hw); - spin_unlock_irqrestore(&ah->txbuflock, flags); - - bf->skb = skb; - - if (ath5k_txbuf_setup(ah, bf, txq, padsize)) { - bf->skb = NULL; - spin_lock_irqsave(&ah->txbuflock, flags); - list_add_tail(&bf->list, &ah->txbuf); - ah->txbuf_len++; - spin_unlock_irqrestore(&ah->txbuflock, flags); - goto drop_packet; - } - return; - -drop_packet: - dev_kfree_skb_any(skb); -} - -static void -ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb, - struct ath5k_txq *txq, struct ath5k_tx_status *ts) -{ - struct ieee80211_tx_info *info; - u8 tries[3]; - int i; - - ah->stats.tx_all_count++; - ah->stats.tx_bytes_count += skb->len; - info = IEEE80211_SKB_CB(skb); - - tries[0] = info->status.rates[0].count; - tries[1] = info->status.rates[1].count; - tries[2] = info->status.rates[2].count; - - ieee80211_tx_info_clear_status(info); - - for (i = 0; i < ts->ts_final_idx; i++) { - struct ieee80211_tx_rate *r = - &info->status.rates[i]; - - r->count = tries[i]; - } - - info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; - info->status.rates[ts->ts_final_idx + 1].idx = -1; - - if (unlikely(ts->ts_status)) { - ah->stats.ack_fail++; - if (ts->ts_status & AR5K_TXERR_FILT) { - info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - ah->stats.txerr_filt++; - } - if (ts->ts_status & AR5K_TXERR_XRETRY) - ah->stats.txerr_retry++; - if (ts->ts_status & AR5K_TXERR_FIFO) - ah->stats.txerr_fifo++; - } else { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts->ts_rssi; - - /* count the successful attempt as well */ - info->status.rates[ts->ts_final_idx].count++; - } - - /* - * Remove MAC header padding before giving the frame - * back to mac80211. - */ - ath5k_remove_padding(skb); - - if (ts->ts_antenna > 0 && ts->ts_antenna < 5) - ah->stats.antenna_tx[ts->ts_antenna]++; - else - ah->stats.antenna_tx[0]++; /* invalid */ - - trace_ath5k_tx_complete(ah, skb, txq, ts); - ieee80211_tx_status(ah->hw, skb); -} - -static void -ath5k_tx_processq(struct ath5k_hw *ah, struct ath5k_txq *txq) -{ - struct ath5k_tx_status ts = {}; - struct ath5k_buf *bf, *bf0; - struct ath5k_desc *ds; - struct sk_buff *skb; - int ret; - - spin_lock(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) { - - txq->txq_poll_mark = false; - - /* skb might already have been processed last time. */ - if (bf->skb != NULL) { - ds = bf->desc; - - ret = ah->ah_proc_tx_desc(ah, ds, &ts); - if (unlikely(ret == -EINPROGRESS)) - break; - else if (unlikely(ret)) { - ATH5K_ERR(ah, - "error %d while processing " - "queue %u\n", ret, txq->qnum); - break; - } - - skb = bf->skb; - bf->skb = NULL; - - dma_unmap_single(ah->dev, bf->skbaddr, skb->len, - DMA_TO_DEVICE); - ath5k_tx_frame_completed(ah, skb, txq, &ts); - } - - /* - * It's possible that the hardware can say the buffer is - * completed when it hasn't yet loaded the ds_link from - * host memory and moved on. - * Always keep the last descriptor to avoid HW races... - */ - if (ath5k_hw_get_txdp(ah, txq->qnum) != bf->daddr) { - spin_lock(&ah->txbuflock); - list_move_tail(&bf->list, &ah->txbuf); - ah->txbuf_len++; - txq->txq_len--; - spin_unlock(&ah->txbuflock); - } - } - spin_unlock(&txq->lock); - if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4) - ieee80211_wake_queue(ah->hw, txq->qnum); -} - -static void -ath5k_tasklet_tx(unsigned long data) -{ - int i; - struct ath5k_hw *ah = (void *)data; - - for (i = 0; i < AR5K_NUM_TX_QUEUES; i++) - if (ah->txqs[i].setup && (ah->ah_txq_isr_txok_all & BIT(i))) - ath5k_tx_processq(ah, &ah->txqs[i]); - - ah->tx_pending = false; - ath5k_set_current_imask(ah); -} - - -/*****************\ -* Beacon handling * -\*****************/ - -/* - * Setup the beacon frame for transmit. - */ -static int -ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf) -{ - struct sk_buff *skb = bf->skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ath5k_desc *ds; - int ret = 0; - u8 antenna; - u32 flags; - const int padsize = 0; - - bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len, - DMA_TO_DEVICE); - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " - "skbaddr %llx\n", skb, skb->data, skb->len, - (unsigned long long)bf->skbaddr); - - if (dma_mapping_error(ah->dev, bf->skbaddr)) { - ATH5K_ERR(ah, "beacon DMA mapping failed\n"); - dev_kfree_skb_any(skb); - bf->skb = NULL; - return -EIO; - } - - ds = bf->desc; - antenna = ah->ah_tx_ant; - - flags = AR5K_TXDESC_NOACK; - if (ah->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) { - ds->ds_link = bf->daddr; /* self-linked */ - flags |= AR5K_TXDESC_VEOL; - } else - ds->ds_link = 0; - - /* - * If we use multiple antennas on AP and use - * the Sectored AP scenario, switch antenna every - * 4 beacons to make sure everybody hears our AP. - * When a client tries to associate, hw will keep - * track of the tx antenna to be used for this client - * automatically, based on ACKed packets. - * - * Note: AP still listens and transmits RTS on the - * default antenna which is supposed to be an omni. - * - * Note2: On sectored scenarios it's possible to have - * multiple antennas (1 omni -- the default -- and 14 - * sectors), so if we choose to actually support this - * mode, we need to allow the user to set how many antennas - * we have and tweak the code below to send beacons - * on all of them. - */ - if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) - antenna = ah->bsent & 4 ? 2 : 1; - - - /* FIXME: If we are in g mode and rate is a CCK rate - * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta - * from tx power (value is in dB units already) */ - ds->ds_data = bf->skbaddr; - ret = ah->ah_setup_tx_desc(ah, ds, skb->len, - ieee80211_get_hdrlen_from_skb(skb), padsize, - AR5K_PKT_TYPE_BEACON, (ah->power_level * 2), - ieee80211_get_tx_rate(ah->hw, info)->hw_value, - 1, AR5K_TXKEYIX_INVALID, - antenna, flags, 0, 0); - if (ret) - goto err_unmap; - - return 0; -err_unmap: - dma_unmap_single(ah->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); - return ret; -} - -/* - * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, - * this is called only once at config_bss time, for AP we do it every - * SWBA interrupt so that the TIM will reflect buffered frames. - * - * Called with the beacon lock. - */ -int -ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - int ret; - struct ath5k_hw *ah = hw->priv; - struct ath5k_vif *avf = (void *)vif->drv_priv; - struct sk_buff *skb; - - if (WARN_ON(!vif)) { - ret = -EINVAL; - goto out; - } - - skb = ieee80211_beacon_get(hw, vif); - - if (!skb) { - ret = -ENOMEM; - goto out; - } - - ath5k_txbuf_free_skb(ah, avf->bbuf); - avf->bbuf->skb = skb; - ret = ath5k_beacon_setup(ah, avf->bbuf); -out: - return ret; -} - -/* - * Transmit a beacon frame at SWBA. Dynamic updates to the - * frame contents are done as needed and the slot time is - * also adjusted based on current state. - * - * This is called from software irq context (beacontq tasklets) - * or user context from ath5k_beacon_config. - */ -static void -ath5k_beacon_send(struct ath5k_hw *ah) -{ - struct ieee80211_vif *vif; - struct ath5k_vif *avf; - struct ath5k_buf *bf; - struct sk_buff *skb; - int err; - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "in beacon_send\n"); - - /* - * Check if the previous beacon has gone out. If - * not, don't don't try to post another: skip this - * period and wait for the next. Missed beacons - * indicate a problem and should not occur. If we - * miss too many consecutive beacons reset the device. - */ - if (unlikely(ath5k_hw_num_tx_pending(ah, ah->bhalq) != 0)) { - ah->bmisscount++; - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, - "missed %u consecutive beacons\n", ah->bmisscount); - if (ah->bmisscount > 10) { /* NB: 10 is a guess */ - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, - "stuck beacon time (%u missed)\n", - ah->bmisscount); - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "stuck beacon, resetting\n"); - ieee80211_queue_work(ah->hw, &ah->reset_work); - } - return; - } - if (unlikely(ah->bmisscount != 0)) { - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, - "resume beacon xmit after %u misses\n", - ah->bmisscount); - ah->bmisscount = 0; - } - - 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); - int slot = ((tsftu % ah->bintval) * ATH_BCBUF) / ah->bintval; - vif = ah->bslot[(slot + 1) % ATH_BCBUF]; - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, - "tsf %llx tsftu %x intval %u slot %u vif %p\n", - (unsigned long long)tsf, tsftu, ah->bintval, slot, vif); - } else /* only one interface */ - vif = ah->bslot[0]; - - if (!vif) - return; - - avf = (void *)vif->drv_priv; - bf = avf->bbuf; - - /* - * Stop any current dma and put the new frame on the queue. - * This should never fail since we check above that no frames - * are still pending on the queue. - */ - if (unlikely(ath5k_hw_stop_beacon_queue(ah, ah->bhalq))) { - ATH5K_WARN(ah, "beacon queue %u didn't start/stop ?\n", ah->bhalq); - /* NB: hw still stops DMA, so proceed */ - } - - /* refresh the beacon for AP or MESH mode */ - if (ah->opmode == NL80211_IFTYPE_AP || - ah->opmode == NL80211_IFTYPE_MESH_POINT) { - err = ath5k_beacon_update(ah->hw, vif); - if (err) - return; - } - - if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || - ah->opmode == NL80211_IFTYPE_MONITOR)) { - ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf->skb); - return; - } - - trace_ath5k_tx(ah, bf->skb, &ah->txqs[ah->bhalq]); - - ath5k_hw_set_txdp(ah, ah->bhalq, bf->daddr); - ath5k_hw_start_tx_dma(ah, ah->bhalq); - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", - ah->bhalq, (unsigned long long)bf->daddr, bf->desc); - - skb = ieee80211_get_buffered_bc(ah->hw, vif); - while (skb) { - ath5k_tx_queue(ah->hw, skb, ah->cabq); - - if (ah->cabq->txq_len >= ah->cabq->txq_max) - break; - - skb = ieee80211_get_buffered_bc(ah->hw, vif); - } - - ah->bsent++; -} - -/** - * ath5k_beacon_update_timers - update beacon timers - * - * @ah: struct ath5k_hw pointer we are operating on - * @bc_tsf: the timestamp of the beacon. 0 to reset the TSF. -1 to perform a - * beacon timer update based on the current HW TSF. - * - * Calculate the next target beacon transmit time (TBTT) based on the timestamp - * of a received beacon or the current local hardware TSF and write it to the - * beacon timer registers. - * - * This is called in a variety of situations, e.g. when a beacon is received, - * when a TSF update has been detected, but also when an new IBSS is created or - * when we otherwise know we have to update the timers, but we keep it in this - * function to have it all together in one place. - */ -void -ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) -{ - u32 nexttbtt, intval, hw_tu, bc_tu; - u64 hw_tsf; - - intval = ah->bintval & AR5K_BEACON_PERIOD; - 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", - intval); - } - if (WARN_ON(!intval)) - return; - - /* beacon TSF converted to TU */ - bc_tu = TSF_TO_TU(bc_tsf); - - /* current TSF converted to TU */ - hw_tsf = ath5k_hw_get_tsf64(ah); - hw_tu = TSF_TO_TU(hw_tsf); - -#define FUDGE (AR5K_TUNE_SW_BEACON_RESP + 3) - /* We use FUDGE to make sure the next TBTT is ahead of the current TU. - * Since we later subtract AR5K_TUNE_SW_BEACON_RESP (10) in the timer - * configuration we need to make sure it is bigger than that. */ - - if (bc_tsf == -1) { - /* - * no beacons received, called internally. - * just need to refresh timers based on HW TSF. - */ - nexttbtt = roundup(hw_tu + FUDGE, intval); - } else if (bc_tsf == 0) { - /* - * no beacon received, probably called by ath5k_reset_tsf(). - * reset TSF to start with 0. - */ - nexttbtt = intval; - intval |= AR5K_BEACON_RESET_TSF; - } else if (bc_tsf > hw_tsf) { - /* - * beacon received, SW merge happened but HW TSF not yet updated. - * not possible to reconfigure timers yet, but next time we - * receive a beacon with the same BSSID, the hardware will - * automatically update the TSF and then we need to reconfigure - * the timers. - */ - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "need to wait for HW TSF sync\n"); - return; - } else { - /* - * most important case for beacon synchronization between STA. - * - * beacon received and HW TSF has been already updated by HW. - * update next TBTT based on the TSF of the beacon, but make - * sure it is ahead of our local TSF timer. - */ - nexttbtt = bc_tu + roundup(hw_tu + FUDGE - bc_tu, intval); - } -#undef FUDGE - - ah->nexttbtt = nexttbtt; - - intval |= AR5K_BEACON_ENA; - ath5k_hw_init_beacon_timers(ah, nexttbtt, intval); - - /* - * debugging output last in order to preserve the time critical aspect - * of this function - */ - if (bc_tsf == -1) - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "reconfigured timers based on HW TSF\n"); - else if (bc_tsf == 0) - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "reset HW TSF and timers\n"); - else - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "updated timers based on beacon TSF\n"); - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, - "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n", - (unsigned long long) bc_tsf, - (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt); - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "intval %u %s %s\n", - intval & AR5K_BEACON_PERIOD, - intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "", - intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); -} - -/** - * ath5k_beacon_config - Configure the beacon queues and interrupts - * - * @ah: struct ath5k_hw pointer we are operating on - * - * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA - * interrupts to detect TSF updates only. - */ -void -ath5k_beacon_config(struct ath5k_hw *ah) -{ - unsigned long flags; - - spin_lock_irqsave(&ah->block, flags); - ah->bmisscount = 0; - ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); - - if (ah->enable_beacon) { - /* - * In IBSS mode we use a self-linked tx descriptor and let the - * hardware send the beacons automatically. We have to load it - * only once here. - * We use the SWBA interrupt only to keep track of the beacon - * timers in order to detect automatic TSF updates. - */ - ath5k_beaconq_config(ah); - - ah->imask |= AR5K_INT_SWBA; - - if (ah->opmode == NL80211_IFTYPE_ADHOC) { - if (ath5k_hw_hasveol(ah)) - ath5k_beacon_send(ah); - } else - ath5k_beacon_update_timers(ah, -1); - } else { - ath5k_hw_stop_beacon_queue(ah, ah->bhalq); - } - - ath5k_hw_set_imr(ah, ah->imask); - mmiowb(); - spin_unlock_irqrestore(&ah->block, flags); -} - -static void ath5k_tasklet_beacon(unsigned long data) -{ - struct ath5k_hw *ah = (struct ath5k_hw *) data; - - /* - * Software beacon alert--time to send a beacon. - * - * In IBSS mode we use this interrupt just to - * keep track of the next TBTT (target beacon - * transmission time) in order to detect whether - * automatic TSF updates happened. - */ - if (ah->opmode == NL80211_IFTYPE_ADHOC) { - /* XXX: only if VEOL supported */ - u64 tsf = ath5k_hw_get_tsf64(ah); - ah->nexttbtt += ah->bintval; - ATH5K_DBG(ah, ATH5K_DEBUG_BEACON, - "SWBA nexttbtt: %x hw_tu: %x " - "TSF: %llx\n", - ah->nexttbtt, - TSF_TO_TU(tsf), - (unsigned long long) tsf); - } else { - spin_lock(&ah->block); - ath5k_beacon_send(ah); - spin_unlock(&ah->block); - } -} - - -/********************\ -* Interrupt handling * -\********************/ - -static void -ath5k_intr_calibration_poll(struct ath5k_hw *ah) -{ - if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) && - !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL) && - !(ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)) { - - /* Run ANI only when calibration is not active */ - - ah->ah_cal_next_ani = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); - tasklet_schedule(&ah->ani_tasklet); - - } else if (time_is_before_eq_jiffies(ah->ah_cal_next_short) && - !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL) && - !(ah->ah_cal_mask & AR5K_CALIBRATION_SHORT)) { - - /* Run calibration only when another calibration - * is not running. - * - * Note: This is for both full/short calibration, - * if it's time for a full one, ath5k_calibrate_work will deal - * with it. */ - - ah->ah_cal_next_short = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_SHORT); - ieee80211_queue_work(ah->hw, &ah->calib_work); - } - /* we could use SWI to generate enough interrupts to meet our - * calibration interval requirements, if necessary: - * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ -} - -static void -ath5k_schedule_rx(struct ath5k_hw *ah) -{ - ah->rx_pending = true; - tasklet_schedule(&ah->rxtq); -} - -static void -ath5k_schedule_tx(struct ath5k_hw *ah) -{ - ah->tx_pending = true; - tasklet_schedule(&ah->txtq); -} - -static irqreturn_t -ath5k_intr(int irq, void *dev_id) -{ - struct ath5k_hw *ah = dev_id; - enum ath5k_int status; - unsigned int counter = 1000; - - - /* - * If hw is not ready (or detached) and we get an - * interrupt, or if we have no interrupts pending - * (that means it's not for us) skip it. - * - * NOTE: Group 0/1 PCI interface registers are not - * supported on WiSOCs, so we can't check for pending - * interrupts (ISR belongs to another register group - * so we are ok). - */ - if (unlikely(test_bit(ATH_STAT_INVALID, ah->status) || - ((ath5k_get_bus_type(ah) != ATH_AHB) && - !ath5k_hw_is_intr_pending(ah)))) - return IRQ_NONE; - - /** Main loop **/ - do { - ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */ - - ATH5K_DBG(ah, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n", - status, ah->imask); - - /* - * Fatal hw error -> Log and reset - * - * Fatal errors are unrecoverable so we have to - * reset the card. These errors include bus and - * dma errors. - */ - if (unlikely(status & AR5K_INT_FATAL)) { - - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "fatal int, resetting\n"); - ieee80211_queue_work(ah->hw, &ah->reset_work); - - /* - * RX Overrun -> Count and reset if needed - * - * Receive buffers are full. Either the bus is busy or - * the CPU is not fast enough to process all received - * frames. - */ - } else if (unlikely(status & AR5K_INT_RXORN)) { - - /* - * Older chipsets need a reset to come out of this - * condition, but we treat it as RX for newer chips. - * We don't know exactly which versions need a reset - * this guess is copied from the HAL. - */ - ah->stats.rxorn_intr++; - - if (ah->ah_mac_srev < AR5K_SREV_AR5212) { - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "rx overrun, resetting\n"); - ieee80211_queue_work(ah->hw, &ah->reset_work); - } else - ath5k_schedule_rx(ah); - - } else { - - /* Software Beacon Alert -> Schedule beacon tasklet */ - if (status & AR5K_INT_SWBA) - tasklet_hi_schedule(&ah->beacontq); - - /* - * No more RX descriptors -> Just count - * - * NB: the hardware should re-read the link when - * RXE bit is written, but it doesn't work at - * least on older hardware revs. - */ - if (status & AR5K_INT_RXEOL) - ah->stats.rxeol_intr++; - - - /* TX Underrun -> Bump tx trigger level */ - if (status & AR5K_INT_TXURN) - ath5k_hw_update_tx_triglevel(ah, true); - - /* RX -> Schedule rx tasklet */ - if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) - ath5k_schedule_rx(ah); - - /* TX -> Schedule tx tasklet */ - if (status & (AR5K_INT_TXOK - | AR5K_INT_TXDESC - | AR5K_INT_TXERR - | AR5K_INT_TXEOL)) - ath5k_schedule_tx(ah); - - /* Missed beacon -> TODO - if (status & AR5K_INT_BMISS) - */ - - /* MIB event -> Update counters and notify ANI */ - if (status & AR5K_INT_MIB) { - ah->stats.mib_intr++; - ath5k_hw_update_mib_counters(ah); - ath5k_ani_mib_intr(ah); - } - - /* GPIO -> Notify RFKill layer */ - if (status & AR5K_INT_GPIO) - tasklet_schedule(&ah->rf_kill.toggleq); - - } - - if (ath5k_get_bus_type(ah) == ATH_AHB) - break; - - } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); - - /* - * Until we handle rx/tx interrupts mask them on IMR - * - * NOTE: ah->(rx/tx)_pending are set when scheduling the tasklets - * and unset after we 've handled the interrupts. - */ - if (ah->rx_pending || ah->tx_pending) - ath5k_set_current_imask(ah); - - if (unlikely(!counter)) - ATH5K_WARN(ah, "too many interrupts, giving up for now\n"); - - /* Fire up calibration poll */ - ath5k_intr_calibration_poll(ah); - - return IRQ_HANDLED; -} - -/* - * Periodically recalibrate the PHY to account - * for temperature/environment changes. - */ -static void -ath5k_calibrate_work(struct work_struct *work) -{ - struct ath5k_hw *ah = container_of(work, struct ath5k_hw, - calib_work); - - /* Should we run a full calibration ? */ - if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { - - ah->ah_cal_next_full = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); - ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; - - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, - "running full calibration\n"); - - if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) { - /* - * Rfgain is out of bounds, reset the chip - * to load new gain values. - */ - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "got new rfgain, resetting\n"); - ieee80211_queue_work(ah->hw, &ah->reset_work); - } - } else - ah->ah_cal_mask |= AR5K_CALIBRATION_SHORT; - - - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", - ieee80211_frequency_to_channel(ah->curchan->center_freq), - ah->curchan->hw_value); - - if (ath5k_hw_phy_calibrate(ah, ah->curchan)) - ATH5K_ERR(ah, "calibration of channel %u failed\n", - ieee80211_frequency_to_channel( - ah->curchan->center_freq)); - - /* Clear calibration flags */ - if (ah->ah_cal_mask & AR5K_CALIBRATION_FULL) - ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; - else if (ah->ah_cal_mask & AR5K_CALIBRATION_SHORT) - ah->ah_cal_mask &= ~AR5K_CALIBRATION_SHORT; -} - - -static void -ath5k_tasklet_ani(unsigned long data) -{ - struct ath5k_hw *ah = (void *)data; - - ah->ah_cal_mask |= AR5K_CALIBRATION_ANI; - ath5k_ani_calibration(ah); - ah->ah_cal_mask &= ~AR5K_CALIBRATION_ANI; -} - - -static void -ath5k_tx_complete_poll_work(struct work_struct *work) -{ - struct ath5k_hw *ah = container_of(work, struct ath5k_hw, - tx_complete_work.work); - struct ath5k_txq *txq; - int i; - bool needreset = false; - - mutex_lock(&ah->lock); - - for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) { - if (ah->txqs[i].setup) { - txq = &ah->txqs[i]; - spin_lock_bh(&txq->lock); - if (txq->txq_len > 1) { - if (txq->txq_poll_mark) { - ATH5K_DBG(ah, ATH5K_DEBUG_XMIT, - "TX queue stuck %d\n", - txq->qnum); - needreset = true; - txq->txq_stuck++; - spin_unlock_bh(&txq->lock); - break; - } else { - txq->txq_poll_mark = true; - } - } - spin_unlock_bh(&txq->lock); - } - } - - if (needreset) { - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "TX queues stuck, resetting\n"); - ath5k_reset(ah, NULL, true); - } - - mutex_unlock(&ah->lock); - - ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work, - msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); -} - - -/*************************\ -* Initialization routines * -\*************************/ - -int __devinit -ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) -{ - struct ieee80211_hw *hw = ah->hw; - struct ath_common *common; - int ret; - int csz; - - /* Initialize driver private data */ - SET_IEEE80211_DEV(hw, ah->dev); - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_REPORTS_TX_ACK_STATUS; - - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_STATION) | - 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; - - hw->extra_tx_headroom = 2; - hw->channel_change_time = 5000; - - /* - * Mark the device as detached to avoid processing - * interrupts until setup is complete. - */ - __set_bit(ATH_STAT_INVALID, ah->status); - - ah->opmode = NL80211_IFTYPE_STATION; - ah->bintval = 1000; - mutex_init(&ah->lock); - spin_lock_init(&ah->rxbuflock); - spin_lock_init(&ah->txbuflock); - spin_lock_init(&ah->block); - spin_lock_init(&ah->irqlock); - - /* Setup interrupt handler */ - ret = request_irq(ah->irq, ath5k_intr, IRQF_SHARED, "ath", ah); - if (ret) { - ATH5K_ERR(ah, "request_irq failed\n"); - goto err; - } - - common = ath5k_hw_common(ah); - common->ops = &ath5k_common_ops; - common->bus_ops = bus_ops; - common->ah = ah; - common->hw = hw; - common->priv = ah; - common->clockrate = 40; - - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - ath5k_read_cachesize(common, &csz); - common->cachelsz = csz << 2; /* convert to bytes */ - - spin_lock_init(&common->cc_lock); - - /* Initialize device */ - ret = ath5k_hw_init(ah); - if (ret) - goto err_irq; - - /* Set up multi-rate retry capabilities */ - if (ah->ah_capabilities.cap_has_mrr_support) { - hw->max_rates = 4; - hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT, - AR5K_INIT_RETRY_LONG); - } - - hw->vif_data_size = sizeof(struct ath5k_vif); - - /* Finish private driver data initialization */ - ret = ath5k_init(hw); - if (ret) - goto err_ah; - - ATH5K_INFO(ah, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", - ath5k_chip_name(AR5K_VERSION_MAC, ah->ah_mac_srev), - ah->ah_mac_srev, - ah->ah_phy_revision); - - if (!ah->ah_single_chip) { - /* Single chip radio (!RF5111) */ - if (ah->ah_radio_5ghz_revision && - !ah->ah_radio_2ghz_revision) { - /* No 5GHz support -> report 2GHz radio */ - if (!test_bit(AR5K_MODE_11A, - ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(ah, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - ah->ah_radio_5ghz_revision), - ah->ah_radio_5ghz_revision); - /* No 2GHz support (5110 and some - * 5GHz only cards) -> report 5GHz radio */ - } else if (!test_bit(AR5K_MODE_11B, - ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(ah, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - ah->ah_radio_5ghz_revision), - ah->ah_radio_5ghz_revision); - /* Multiband radio */ - } else { - ATH5K_INFO(ah, "RF%s multiband radio found" - " (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - ah->ah_radio_5ghz_revision), - ah->ah_radio_5ghz_revision); - } - } - /* Multi chip radio (RF5111 - RF2111) -> - * report both 2GHz/5GHz radios */ - else if (ah->ah_radio_5ghz_revision && - ah->ah_radio_2ghz_revision) { - ATH5K_INFO(ah, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - ah->ah_radio_5ghz_revision), - ah->ah_radio_5ghz_revision); - ATH5K_INFO(ah, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - ah->ah_radio_2ghz_revision), - ah->ah_radio_2ghz_revision); - } - } - - ath5k_debug_init_device(ah); - - /* ready to process interrupts */ - __clear_bit(ATH_STAT_INVALID, ah->status); - - return 0; -err_ah: - ath5k_hw_deinit(ah); -err_irq: - free_irq(ah->irq, ah); -err: - return ret; -} - -static int -ath5k_stop_locked(struct ath5k_hw *ah) -{ - - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "invalid %u\n", - test_bit(ATH_STAT_INVALID, ah->status)); - - /* - * Shutdown the hardware and driver: - * stop output from above - * disable interrupts - * turn off timers - * turn off the radio - * clear transmit machinery - * clear receive machinery - * drain and release tx queues - * reclaim beacon resources - * power down hardware - * - * Note that some of this work is not possible if the - * hardware is gone (invalid). - */ - ieee80211_stop_queues(ah->hw); - - if (!test_bit(ATH_STAT_INVALID, ah->status)) { - ath5k_led_off(ah); - ath5k_hw_set_imr(ah, 0); - synchronize_irq(ah->irq); - ath5k_rx_stop(ah); - ath5k_hw_dma_stop(ah); - ath5k_drain_tx_buffs(ah); - ath5k_hw_phy_disable(ah); - } - - return 0; -} - -int ath5k_start(struct ieee80211_hw *hw) -{ - struct ath5k_hw *ah = hw->priv; - struct ath_common *common = ath5k_hw_common(ah); - int ret, i; - - mutex_lock(&ah->lock); - - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "mode %d\n", ah->opmode); - - /* - * Stop anything previously setup. This is safe - * no matter this is the first time through or not. - */ - ath5k_stop_locked(ah); - - /* - * The basic interface to setting the hardware in a good - * state is ``reset''. On return the hardware is known to - * be powered up and with interrupts disabled. This must - * be followed by initialization of the appropriate bits - * and then setup of the interrupt mask. - */ - ah->curchan = ah->hw->conf.channel; - ah->imask = AR5K_INT_RXOK - | AR5K_INT_RXERR - | AR5K_INT_RXEOL - | AR5K_INT_RXORN - | AR5K_INT_TXDESC - | AR5K_INT_TXEOL - | AR5K_INT_FATAL - | AR5K_INT_GLOBAL - | AR5K_INT_MIB; - - ret = ath5k_reset(ah, NULL, false); - if (ret) - goto done; - - if (!ath5k_modparam_no_hw_rfkill_switch) - ath5k_rfkill_hw_start(ah); - - /* - * Reset the key cache since some parts do not reset the - * contents on initial power up or resume from suspend. - */ - for (i = 0; i < common->keymax; i++) - ath_hw_keyreset(common, (u16) i); - - /* Use higher rates for acks instead of base - * rate */ - ah->ah_ack_bitrate_high = true; - - for (i = 0; i < ARRAY_SIZE(ah->bslot); i++) - ah->bslot[i] = NULL; - - ret = 0; -done: - mmiowb(); - mutex_unlock(&ah->lock); - - ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work, - msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); - - return ret; -} - -static void ath5k_stop_tasklets(struct ath5k_hw *ah) -{ - ah->rx_pending = false; - ah->tx_pending = false; - tasklet_kill(&ah->rxtq); - tasklet_kill(&ah->txtq); - tasklet_kill(&ah->beacontq); - tasklet_kill(&ah->ani_tasklet); -} - -/* - * Stop the device, grabbing the top-level lock to protect - * against concurrent entry through ath5k_init (which can happen - * if another thread does a system call and the thread doing the - * stop is preempted). - */ -void ath5k_stop(struct ieee80211_hw *hw) -{ - struct ath5k_hw *ah = hw->priv; - int ret; - - mutex_lock(&ah->lock); - ret = ath5k_stop_locked(ah); - if (ret == 0 && !test_bit(ATH_STAT_INVALID, ah->status)) { - /* - * Don't set the card in full sleep mode! - * - * a) When the device is in this state it must be carefully - * woken up or references to registers in the PCI clock - * domain may freeze the bus (and system). This varies - * by chip and is mostly an issue with newer parts - * (madwifi sources mentioned srev >= 0x78) that go to - * sleep more quickly. - * - * b) On older chips full sleep results a weird behaviour - * during wakeup. I tested various cards with srev < 0x78 - * and they don't wake up after module reload, a second - * module reload is needed to bring the card up again. - * - * Until we figure out what's going on don't enable - * full chip reset on any chip (this is what Legacy HAL - * and Sam's HAL do anyway). Instead Perform a full reset - * on the device (same as initial state after attach) and - * leave it idle (keep MAC/BB on warm reset) */ - ret = ath5k_hw_on_hold(ah); - - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "putting device to sleep\n"); - } - - mmiowb(); - mutex_unlock(&ah->lock); - - ath5k_stop_tasklets(ah); - - cancel_delayed_work_sync(&ah->tx_complete_work); - - if (!ath5k_modparam_no_hw_rfkill_switch) - ath5k_rfkill_hw_stop(ah); -} - -/* - * Reset the hardware. If chan is not NULL, then also pause rx/tx - * and change to the given channel. - * - * This should be called with ah->lock. - */ -static int -ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, - bool skip_pcu) -{ - struct ath_common *common = ath5k_hw_common(ah); - int ret, ani_mode; - bool fast; - - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n"); - - ath5k_hw_set_imr(ah, 0); - synchronize_irq(ah->irq); - ath5k_stop_tasklets(ah); - - /* Save ani mode and disable ANI during - * reset. If we don't we might get false - * PHY error interrupts. */ - ani_mode = ah->ani_state.ani_mode; - ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF); - - /* We are going to empty hw queues - * so we should also free any remaining - * tx buffers */ - ath5k_drain_tx_buffs(ah); - if (chan) - ah->curchan = chan; - - fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; - - ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu); - if (ret) { - ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret); - goto err; - } - - ret = ath5k_rx_start(ah); - if (ret) { - ATH5K_ERR(ah, "can't start recv logic\n"); - goto err; - } - - ath5k_ani_init(ah, ani_mode); - - /* - * Set calibration intervals - * - * Note: We don't need to run calibration imediately - * since some initial calibration is done on reset - * even for fast channel switching. Also on scanning - * this will get set again and again and it won't get - * executed unless we connect somewhere and spend some - * time on the channel (that's what calibration needs - * anyway to be accurate). - */ - ah->ah_cal_next_full = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); - ah->ah_cal_next_ani = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); - ah->ah_cal_next_short = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_SHORT); - - ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); - - /* clear survey data and cycle counters */ - memset(&ah->survey, 0, sizeof(ah->survey)); - spin_lock_bh(&common->cc_lock); - ath_hw_cycle_counters_update(common); - memset(&common->cc_survey, 0, sizeof(common->cc_survey)); - memset(&common->cc_ani, 0, sizeof(common->cc_ani)); - spin_unlock_bh(&common->cc_lock); - - /* - * Change channels and update the h/w rate map if we're switching; - * e.g. 11a to 11b/g. - * - * We may be doing a reset in response to an ioctl that changes the - * channel so update any state that might change as a result. - * - * XXX needed? - */ -/* ath5k_chan_change(ah, c); */ - - ath5k_beacon_config(ah); - /* intrs are enabled by ath5k_beacon_config */ - - ieee80211_wake_queues(ah->hw); - - return 0; -err: - return ret; -} - -static void ath5k_reset_work(struct work_struct *work) -{ - struct ath5k_hw *ah = container_of(work, struct ath5k_hw, - reset_work); - - mutex_lock(&ah->lock); - ath5k_reset(ah, NULL, true); - mutex_unlock(&ah->lock); -} - -static int __devinit -ath5k_init(struct ieee80211_hw *hw) -{ - - struct ath5k_hw *ah = hw->priv; - struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); - struct ath5k_txq *txq; - u8 mac[ETH_ALEN] = {}; - int ret; - - - /* - * Collect the channel list. The 802.11 layer - * is responsible for filtering this list based - * on settings like the phy mode and regulatory - * domain restrictions. - */ - ret = ath5k_setup_bands(hw); - if (ret) { - ATH5K_ERR(ah, "can't get channels\n"); - goto err; - } - - /* - * Allocate tx+rx descriptors and populate the lists. - */ - ret = ath5k_desc_alloc(ah); - if (ret) { - ATH5K_ERR(ah, "can't allocate descriptors\n"); - goto err; - } - - /* - * Allocate hardware transmit queues: one queue for - * beacon frames and one data queue for each QoS - * priority. Note that hw functions handle resetting - * these queues at the needed time. - */ - ret = ath5k_beaconq_setup(ah); - if (ret < 0) { - ATH5K_ERR(ah, "can't setup a beacon xmit queue\n"); - goto err_desc; - } - ah->bhalq = ret; - ah->cabq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_CAB, 0); - if (IS_ERR(ah->cabq)) { - ATH5K_ERR(ah, "can't setup cab queue\n"); - ret = PTR_ERR(ah->cabq); - goto err_bhal; - } - - /* 5211 and 5212 usually support 10 queues but we better rely on the - * capability information */ - if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) { - /* This order matches mac80211's queue priority, so we can - * directly use the mac80211 queue number without any mapping */ - txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); - if (IS_ERR(txq)) { - ATH5K_ERR(ah, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); - if (IS_ERR(txq)) { - ATH5K_ERR(ah, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); - if (IS_ERR(txq)) { - ATH5K_ERR(ah, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); - if (IS_ERR(txq)) { - ATH5K_ERR(ah, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - hw->queues = 4; - } else { - /* older hardware (5210) can only support one data queue */ - txq = ath5k_txq_setup(ah, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); - if (IS_ERR(txq)) { - ATH5K_ERR(ah, "can't setup xmit queue\n"); - ret = PTR_ERR(txq); - goto err_queues; - } - hw->queues = 1; - } - - tasklet_init(&ah->rxtq, ath5k_tasklet_rx, (unsigned long)ah); - tasklet_init(&ah->txtq, ath5k_tasklet_tx, (unsigned long)ah); - tasklet_init(&ah->beacontq, ath5k_tasklet_beacon, (unsigned long)ah); - tasklet_init(&ah->ani_tasklet, ath5k_tasklet_ani, (unsigned long)ah); - - INIT_WORK(&ah->reset_work, ath5k_reset_work); - INIT_WORK(&ah->calib_work, ath5k_calibrate_work); - INIT_DELAYED_WORK(&ah->tx_complete_work, ath5k_tx_complete_poll_work); - - ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); - if (ret) { - ATH5K_ERR(ah, "unable to read address from EEPROM\n"); - goto err_queues; - } - - SET_IEEE80211_PERM_ADDR(hw, mac); - /* All MAC address bits matter for ACKs */ - ath5k_update_bssid_mask_and_opmode(ah, NULL); - - regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; - ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); - if (ret) { - ATH5K_ERR(ah, "can't initialize regulatory system\n"); - goto err_queues; - } - - ret = ieee80211_register_hw(hw); - if (ret) { - ATH5K_ERR(ah, "can't register ieee80211 hw\n"); - goto err_queues; - } - - if (!ath_is_world_regd(regulatory)) - regulatory_hint(hw->wiphy, regulatory->alpha2); - - ath5k_init_leds(ah); - - ath5k_sysfs_register(ah); - - return 0; -err_queues: - ath5k_txq_release(ah); -err_bhal: - ath5k_hw_release_tx_queue(ah, ah->bhalq); -err_desc: - ath5k_desc_free(ah); -err: - return ret; -} - -void -ath5k_deinit_ah(struct ath5k_hw *ah) -{ - struct ieee80211_hw *hw = ah->hw; - - /* - * NB: the order of these is important: - * o call the 802.11 layer before detaching ath5k_hw to - * ensure callbacks into the driver to delete global - * key cache entries can be handled - * o reclaim the tx queue data structures after calling - * the 802.11 layer as we'll get called back to reclaim - * node state and potentially want to use them - * o to cleanup the tx queues the hal is called, so detach - * it last - * XXX: ??? detach ath5k_hw ??? - * Other than that, it's straightforward... - */ - ieee80211_unregister_hw(hw); - ath5k_desc_free(ah); - ath5k_txq_release(ah); - ath5k_hw_release_tx_queue(ah, ah->bhalq); - ath5k_unregister_leds(ah); - - ath5k_sysfs_unregister(ah); - /* - * NB: can't reclaim these until after ieee80211_ifdetach - * returns because we'll get called back to reclaim node - * state and potentially want to use them. - */ - ath5k_hw_deinit(ah); - free_irq(ah->irq, ah); -} - -bool -ath5k_any_vif_assoc(struct ath5k_hw *ah) -{ - struct ath5k_vif_iter_data iter_data; - iter_data.hw_macaddr = NULL; - iter_data.any_assoc = false; - iter_data.need_set_hw_addr = false; - iter_data.found_active = true; - - ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, - &iter_data); - return iter_data.any_assoc; -} - -void -ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable) -{ - struct ath5k_hw *ah = hw->priv; - u32 rfilt; - rfilt = ath5k_hw_get_rx_filter(ah); - if (enable) - rfilt |= AR5K_RX_FILTER_BEACON; - else - rfilt &= ~AR5K_RX_FILTER_BEACON; - ath5k_hw_set_rx_filter(ah, rfilt); - ah->filter_flags = rfilt; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/base.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/base.h deleted file mode 100644 index 6c94c7ff..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/base.h +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - * - */ - -/* - * Definitions for the Atheros Wireless LAN controller driver. - */ -#ifndef _DEV_ATH5K_BASE_H -#define _DEV_ATH5K_BASE_H - -struct ieee80211_vif; -struct ieee80211_hw; -struct ath5k_hw; -struct ath5k_txq; -struct ieee80211_channel; -struct ath_bus_ops; -enum nl80211_iftype; - -enum ath5k_srev_type { - AR5K_VERSION_MAC, - AR5K_VERSION_RAD, -}; - -struct ath5k_srev_name { - const char *sr_name; - enum ath5k_srev_type sr_type; - u_int sr_val; -}; - -struct ath5k_buf { - struct list_head list; - struct ath5k_desc *desc; /* virtual addr of desc */ - dma_addr_t daddr; /* physical addr of desc */ - struct sk_buff *skb; /* skbuff for buf */ - dma_addr_t skbaddr;/* physical addr of skb data */ -}; - -struct ath5k_vif { - bool assoc; /* are we associated or not */ - enum nl80211_iftype opmode; - int bslot; - struct ath5k_buf *bbuf; /* beacon buffer */ -}; - -struct ath5k_vif_iter_data { - const u8 *hw_macaddr; - u8 mask[ETH_ALEN]; - u8 active_mac[ETH_ALEN]; /* first active MAC */ - bool need_set_hw_addr; - bool found_active; - bool any_assoc; - enum nl80211_iftype opmode; - int n_stas; -}; - -void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif); -bool ath5k_any_vif_assoc(struct ath5k_hw *ah); - -int ath5k_start(struct ieee80211_hw *hw); -void ath5k_stop(struct ieee80211_hw *hw); - -void ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf); -int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); -void ath5k_beacon_config(struct ath5k_hw *ah); -void ath5k_set_beacon_filter(struct ieee80211_hw *hw, bool enable); - -void ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah, - struct ieee80211_vif *vif); -int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan); -void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf); -void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf); -void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq); - -const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); - -int ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops); -void ath5k_deinit_ah(struct ath5k_hw *ah); - -/* Check whether BSSID mask is supported */ -#define ath5k_hw_hasbssidmask(_ah) (ah->ah_version == AR5K_AR5212) - -/* Check whether virtual EOL is supported */ -#define ath5k_hw_hasveol(_ah) (ah->ah_version != AR5K_AR5210) - -#endif /* _DEV_ATH5K_BASE_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/caps.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/caps.c deleted file mode 100644 index 994169ad..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/caps.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/**************\ -* Capabilities * -\**************/ - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" -#include "../regd.h" - -/* - * Fill the capabilities struct - * TODO: Merge this with EEPROM code when we are done with it - */ -int ath5k_hw_set_capabilities(struct ath5k_hw *ah) -{ - struct ath5k_capabilities *caps = &ah->ah_capabilities; - u16 ee_header; - - /* Capabilities stored in the EEPROM */ - ee_header = caps->cap_eeprom.ee_header; - - if (ah->ah_version == AR5K_AR5210) { - /* - * Set radio capabilities - * (The AR5110 only supports the middle 5GHz band) - */ - caps->cap_range.range_5ghz_min = 5120; - caps->cap_range.range_5ghz_max = 5430; - caps->cap_range.range_2ghz_min = 0; - caps->cap_range.range_2ghz_max = 0; - - /* Set supported modes */ - __set_bit(AR5K_MODE_11A, caps->cap_mode); - } else { - /* - * XXX The transceiver supports frequencies from 4920 to 6100MHz - * XXX and from 2312 to 2732MHz. There are problems with the - * XXX current ieee80211 implementation because the IEEE - * XXX channel mapping does not support negative channel - * XXX numbers (2312MHz is channel -19). Of course, this - * XXX doesn't matter because these channels are out of the - * XXX legal range. - */ - - /* - * Set radio capabilities - */ - - if (AR5K_EEPROM_HDR_11A(ee_header)) { - if (ath_is_49ghz_allowed(caps->cap_eeprom.ee_regdomain)) - caps->cap_range.range_5ghz_min = 4920; - else - caps->cap_range.range_5ghz_min = 5005; - caps->cap_range.range_5ghz_max = 6100; - - /* Set supported modes */ - __set_bit(AR5K_MODE_11A, caps->cap_mode); - } - - /* Enable 802.11b if a 2GHz capable radio (2111/5112) is - * connected */ - if (AR5K_EEPROM_HDR_11B(ee_header) || - (AR5K_EEPROM_HDR_11G(ee_header) && - ah->ah_version != AR5K_AR5211)) { - /* 2312 */ - caps->cap_range.range_2ghz_min = 2412; - caps->cap_range.range_2ghz_max = 2732; - - /* Override 2GHz modes on SoCs that need it - * NOTE: cap_needs_2GHz_ovr gets set from - * ath_ahb_probe */ - if (!caps->cap_needs_2GHz_ovr) { - if (AR5K_EEPROM_HDR_11B(ee_header)) - __set_bit(AR5K_MODE_11B, - caps->cap_mode); - - if (AR5K_EEPROM_HDR_11G(ee_header) && - ah->ah_version != AR5K_AR5211) - __set_bit(AR5K_MODE_11G, - caps->cap_mode); - } - } - } - - if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112) - __clear_bit(AR5K_MODE_11A, caps->cap_mode); - - /* Set number of supported TX queues */ - if (ah->ah_version == AR5K_AR5210) - caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; - else - caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; - - /* Newer hardware has PHY error counters */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5213A) - caps->cap_has_phyerr_counters = true; - else - caps->cap_has_phyerr_counters = false; - - /* MACs since AR5212 have MRR support */ - if (ah->ah_version == AR5K_AR5212) - caps->cap_has_mrr_support = true; - else - caps->cap_has_mrr_support = false; - - return 0; -} - -/* - * TODO: Following functions should be part of a new function - * set_capability - */ - -int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, - u16 assoc_id) -{ - if (ah->ah_version == AR5K_AR5210) { - AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, - AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); - return 0; - } - - return -EIO; -} - -int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) -{ - if (ah->ah_version == AR5K_AR5210) { - AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, - AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); - return 0; - } - - return -EIO; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/debug.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/debug.c deleted file mode 100644 index e5e8f45d..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/debug.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* - * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com> - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file 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, see <http://www.gnu.org/licenses/>. - * - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2004-2005 Atheros Communications, Inc. - * Copyright (c) 2006 Devicescape Software, Inc. - * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - */ -#include <linux/export.h> -#include <linux/moduleparam.h> - -#include <linux/seq_file.h> -#include <linux/list.h> -#include "debug.h" -#include "ath5k.h" -#include "reg.h" -#include "base.h" - -static unsigned int ath5k_debug; -module_param_named(debug, ath5k_debug, uint, 0); - - -/* debugfs: registers */ - -struct reg { - const char *name; - int addr; -}; - -#define REG_STRUCT_INIT(r) { #r, r } - -/* just a few random registers, might want to add more */ -static const struct reg regs[] = { - REG_STRUCT_INIT(AR5K_CR), - REG_STRUCT_INIT(AR5K_RXDP), - REG_STRUCT_INIT(AR5K_CFG), - REG_STRUCT_INIT(AR5K_IER), - REG_STRUCT_INIT(AR5K_BCR), - REG_STRUCT_INIT(AR5K_RTSD0), - REG_STRUCT_INIT(AR5K_RTSD1), - REG_STRUCT_INIT(AR5K_TXCFG), - REG_STRUCT_INIT(AR5K_RXCFG), - REG_STRUCT_INIT(AR5K_RXJLA), - REG_STRUCT_INIT(AR5K_MIBC), - REG_STRUCT_INIT(AR5K_TOPS), - REG_STRUCT_INIT(AR5K_RXNOFRM), - REG_STRUCT_INIT(AR5K_TXNOFRM), - REG_STRUCT_INIT(AR5K_RPGTO), - REG_STRUCT_INIT(AR5K_RFCNT), - REG_STRUCT_INIT(AR5K_MISC), - REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT), - REG_STRUCT_INIT(AR5K_ISR), - REG_STRUCT_INIT(AR5K_PISR), - REG_STRUCT_INIT(AR5K_SISR0), - REG_STRUCT_INIT(AR5K_SISR1), - REG_STRUCT_INIT(AR5K_SISR2), - REG_STRUCT_INIT(AR5K_SISR3), - REG_STRUCT_INIT(AR5K_SISR4), - REG_STRUCT_INIT(AR5K_IMR), - REG_STRUCT_INIT(AR5K_PIMR), - REG_STRUCT_INIT(AR5K_SIMR0), - REG_STRUCT_INIT(AR5K_SIMR1), - REG_STRUCT_INIT(AR5K_SIMR2), - REG_STRUCT_INIT(AR5K_SIMR3), - REG_STRUCT_INIT(AR5K_SIMR4), - REG_STRUCT_INIT(AR5K_DCM_ADDR), - REG_STRUCT_INIT(AR5K_DCCFG), - REG_STRUCT_INIT(AR5K_CCFG), - REG_STRUCT_INIT(AR5K_CPC0), - REG_STRUCT_INIT(AR5K_CPC1), - REG_STRUCT_INIT(AR5K_CPC2), - REG_STRUCT_INIT(AR5K_CPC3), - REG_STRUCT_INIT(AR5K_CPCOVF), - REG_STRUCT_INIT(AR5K_RESET_CTL), - REG_STRUCT_INIT(AR5K_SLEEP_CTL), - REG_STRUCT_INIT(AR5K_INTPEND), - REG_STRUCT_INIT(AR5K_SFR), - REG_STRUCT_INIT(AR5K_PCICFG), - REG_STRUCT_INIT(AR5K_GPIOCR), - REG_STRUCT_INIT(AR5K_GPIODO), - REG_STRUCT_INIT(AR5K_SREV), -}; - -static void *reg_start(struct seq_file *seq, loff_t *pos) -{ - return *pos < ARRAY_SIZE(regs) ? (void *)®s[*pos] : NULL; -} - -static void reg_stop(struct seq_file *seq, void *p) -{ - /* nothing to do */ -} - -static void *reg_next(struct seq_file *seq, void *p, loff_t *pos) -{ - ++*pos; - return *pos < ARRAY_SIZE(regs) ? (void *)®s[*pos] : NULL; -} - -static int reg_show(struct seq_file *seq, void *p) -{ - struct ath5k_hw *ah = seq->private; - struct reg *r = p; - seq_printf(seq, "%-25s0x%08x\n", r->name, - ath5k_hw_reg_read(ah, r->addr)); - return 0; -} - -static const struct seq_operations register_seq_ops = { - .start = reg_start, - .next = reg_next, - .stop = reg_stop, - .show = reg_show -}; - -static int open_file_registers(struct inode *inode, struct file *file) -{ - struct seq_file *s; - int res; - res = seq_open(file, ®ister_seq_ops); - if (res == 0) { - s = file->private_data; - s->private = inode->i_private; - } - return res; -} - -static const struct file_operations fops_registers = { - .open = open_file_registers, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, - .owner = THIS_MODULE, -}; - - -/* debugfs: beacons */ - -static ssize_t read_file_beacon(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[500]; - unsigned int len = 0; - unsigned int v; - u64 tsf; - - v = ath5k_hw_reg_read(ah, AR5K_BEACON); - len += snprintf(buf + len, sizeof(buf) - len, - "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n", - "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD, - (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S); - - len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n", - "AR5K_LAST_TSTP", ath5k_hw_reg_read(ah, AR5K_LAST_TSTP)); - - len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\n\n", - "AR5K_BEACON_CNT", ath5k_hw_reg_read(ah, AR5K_BEACON_CNT)); - - v = ath5k_hw_reg_read(ah, AR5K_TIMER0); - len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", - "AR5K_TIMER0 (TBTT)", v, v); - - v = ath5k_hw_reg_read(ah, AR5K_TIMER1); - len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", - "AR5K_TIMER1 (DMA)", v, v >> 3); - - v = ath5k_hw_reg_read(ah, AR5K_TIMER2); - len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", - "AR5K_TIMER2 (SWBA)", v, v >> 3); - - v = ath5k_hw_reg_read(ah, AR5K_TIMER3); - len += snprintf(buf + len, sizeof(buf) - len, "%-24s0x%08x\tTU: %08x\n", - "AR5K_TIMER3 (ATIM)", v, v); - - tsf = ath5k_hw_get_tsf64(ah); - len += snprintf(buf + len, sizeof(buf) - len, - "TSF\t\t0x%016llx\tTU: %08x\n", - (unsigned long long)tsf, TSF_TO_TU(tsf)); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_beacon(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[20]; - - if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) - return -EFAULT; - - if (strncmp(buf, "disable", 7) == 0) { - AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); - printk(KERN_INFO "debugfs disable beacons\n"); - } else if (strncmp(buf, "enable", 6) == 0) { - AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); - printk(KERN_INFO "debugfs enable beacons\n"); - } - return count; -} - -static const struct file_operations fops_beacon = { - .read = read_file_beacon, - .write = write_file_beacon, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - - -/* debugfs: reset */ - -static ssize_t write_file_reset(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "debug file triggered reset\n"); - ieee80211_queue_work(ah->hw, &ah->reset_work); - return count; -} - -static const struct file_operations fops_reset = { - .write = write_file_reset, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = noop_llseek, -}; - - -/* debugfs: debug level */ - -static const struct { - enum ath5k_debug_level level; - const char *name; - const char *desc; -} dbg_info[] = { - { ATH5K_DEBUG_RESET, "reset", "reset and initialization" }, - { ATH5K_DEBUG_INTR, "intr", "interrupt handling" }, - { ATH5K_DEBUG_MODE, "mode", "mode init/setup" }, - { ATH5K_DEBUG_XMIT, "xmit", "basic xmit operation" }, - { ATH5K_DEBUG_BEACON, "beacon", "beacon handling" }, - { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, - { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, - { ATH5K_DEBUG_LED, "led", "LED management" }, - { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, - { ATH5K_DEBUG_DMA, "dma", "dma start/stop" }, - { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, - { ATH5K_DEBUG_DESC, "desc", "descriptor chains" }, - { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, -}; - -static ssize_t read_file_debug(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[700]; - unsigned int len = 0; - unsigned int i; - - len += snprintf(buf + len, sizeof(buf) - len, - "DEBUG LEVEL: 0x%08x\n\n", ah->debug.level); - - for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) { - len += snprintf(buf + len, sizeof(buf) - len, - "%10s %c 0x%08x - %s\n", dbg_info[i].name, - ah->debug.level & dbg_info[i].level ? '+' : ' ', - dbg_info[i].level, dbg_info[i].desc); - } - len += snprintf(buf + len, sizeof(buf) - len, - "%10s %c 0x%08x - %s\n", dbg_info[i].name, - ah->debug.level == dbg_info[i].level ? '+' : ' ', - dbg_info[i].level, dbg_info[i].desc); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_debug(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - unsigned int i; - char buf[20]; - - if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) - return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(dbg_info); i++) { - if (strncmp(buf, dbg_info[i].name, - strlen(dbg_info[i].name)) == 0) { - ah->debug.level ^= dbg_info[i].level; /* toggle bit */ - break; - } - } - return count; -} - -static const struct file_operations fops_debug = { - .read = read_file_debug, - .write = write_file_debug, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - - -/* debugfs: antenna */ - -static ssize_t read_file_antenna(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[700]; - unsigned int len = 0; - unsigned int i; - unsigned int v; - - len += snprintf(buf + len, sizeof(buf) - len, "antenna mode\t%d\n", - ah->ah_ant_mode); - len += snprintf(buf + len, sizeof(buf) - len, "default antenna\t%d\n", - ah->ah_def_ant); - len += snprintf(buf + len, sizeof(buf) - len, "tx antenna\t%d\n", - ah->ah_tx_ant); - - len += snprintf(buf + len, sizeof(buf) - len, "\nANTENNA\t\tRX\tTX\n"); - for (i = 1; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) { - len += snprintf(buf + len, sizeof(buf) - len, - "[antenna %d]\t%d\t%d\n", - i, ah->stats.antenna_rx[i], ah->stats.antenna_tx[i]); - } - len += snprintf(buf + len, sizeof(buf) - len, "[invalid]\t%d\t%d\n", - ah->stats.antenna_rx[0], ah->stats.antenna_tx[0]); - - v = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); - len += snprintf(buf + len, sizeof(buf) - len, - "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v); - - v = ath5k_hw_reg_read(ah, AR5K_STA_ID1); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n", - (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_STA_ID1_DESC_ANTENNA\t%d\n", - (v & AR5K_STA_ID1_DESC_ANTENNA) != 0); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n", - (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n", - (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0); - - v = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL); - len += snprintf(buf + len, sizeof(buf) - len, - "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n", - (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0); - - v = ath5k_hw_reg_read(ah, AR5K_PHY_RESTART); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_PHY_RESTART_DIV_GC\t\t%x\n", - (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S); - - v = ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ANT_DIV); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", - (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); - - v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_0); - len += snprintf(buf + len, sizeof(buf) - len, - "\nAR5K_PHY_ANT_SWITCH_TABLE_0\t0x%08x\n", v); - v = ath5k_hw_reg_read(ah, AR5K_PHY_ANT_SWITCH_TABLE_1); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_antenna(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - unsigned int i; - char buf[20]; - - if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) - return -EFAULT; - - if (strncmp(buf, "diversity", 9) == 0) { - ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); - printk(KERN_INFO "ath5k debug: enable diversity\n"); - } else if (strncmp(buf, "fixed-a", 7) == 0) { - ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A); - printk(KERN_INFO "ath5k debugfs: fixed antenna A\n"); - } else if (strncmp(buf, "fixed-b", 7) == 0) { - ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B); - printk(KERN_INFO "ath5k debug: fixed antenna B\n"); - } else if (strncmp(buf, "clear", 5) == 0) { - for (i = 0; i < ARRAY_SIZE(ah->stats.antenna_rx); i++) { - ah->stats.antenna_rx[i] = 0; - ah->stats.antenna_tx[i] = 0; - } - printk(KERN_INFO "ath5k debug: cleared antenna stats\n"); - } - return count; -} - -static const struct file_operations fops_antenna = { - .read = read_file_antenna, - .write = write_file_antenna, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -/* debugfs: misc */ - -static ssize_t read_file_misc(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[700]; - unsigned int len = 0; - u32 filt = ath5k_hw_get_rx_filter(ah); - - len += snprintf(buf + len, sizeof(buf) - len, "bssid-mask: %pM\n", - ah->bssidmask); - len += snprintf(buf + len, sizeof(buf) - len, "filter-flags: 0x%x ", - filt); - if (filt & AR5K_RX_FILTER_UCAST) - len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); - if (filt & AR5K_RX_FILTER_MCAST) - len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); - if (filt & AR5K_RX_FILTER_BCAST) - len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); - if (filt & AR5K_RX_FILTER_CONTROL) - len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); - if (filt & AR5K_RX_FILTER_BEACON) - len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); - if (filt & AR5K_RX_FILTER_PROM) - len += snprintf(buf + len, sizeof(buf) - len, " PROM"); - if (filt & AR5K_RX_FILTER_XRPOLL) - len += snprintf(buf + len, sizeof(buf) - len, " XRPOLL"); - if (filt & AR5K_RX_FILTER_PROBEREQ) - len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); - if (filt & AR5K_RX_FILTER_PHYERR_5212) - len += snprintf(buf + len, sizeof(buf) - len, " PHYERR-5212"); - if (filt & AR5K_RX_FILTER_RADARERR_5212) - len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5212"); - if (filt & AR5K_RX_FILTER_PHYERR_5211) - snprintf(buf + len, sizeof(buf) - len, " PHYERR-5211"); - if (filt & AR5K_RX_FILTER_RADARERR_5211) - len += snprintf(buf + len, sizeof(buf) - len, " RADARERR-5211"); - - len += snprintf(buf + len, sizeof(buf) - len, "\nopmode: %s (%d)\n", - ath_opmode_to_string(ah->opmode), ah->opmode); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_misc = { - .read = read_file_misc, - .open = simple_open, - .owner = THIS_MODULE, -}; - - -/* debugfs: frameerrors */ - -static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - struct ath5k_statistics *st = &ah->stats; - char buf[700]; - unsigned int len = 0; - int i; - - len += snprintf(buf + len, sizeof(buf) - len, - "RX\n---------------------\n"); - len += snprintf(buf + len, sizeof(buf) - len, "CRC\t%u\t(%u%%)\n", - st->rxerr_crc, - st->rx_all_count > 0 ? - st->rxerr_crc * 100 / st->rx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "PHY\t%u\t(%u%%)\n", - st->rxerr_phy, - st->rx_all_count > 0 ? - st->rxerr_phy * 100 / st->rx_all_count : 0); - for (i = 0; i < 32; i++) { - if (st->rxerr_phy_code[i]) - len += snprintf(buf + len, sizeof(buf) - len, - " phy_err[%u]\t%u\n", - i, st->rxerr_phy_code[i]); - } - - len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n", - st->rxerr_fifo, - st->rx_all_count > 0 ? - st->rxerr_fifo * 100 / st->rx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "decrypt\t%u\t(%u%%)\n", - st->rxerr_decrypt, - st->rx_all_count > 0 ? - st->rxerr_decrypt * 100 / st->rx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "MIC\t%u\t(%u%%)\n", - st->rxerr_mic, - st->rx_all_count > 0 ? - st->rxerr_mic * 100 / st->rx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "process\t%u\t(%u%%)\n", - st->rxerr_proc, - st->rx_all_count > 0 ? - st->rxerr_proc * 100 / st->rx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "jumbo\t%u\t(%u%%)\n", - st->rxerr_jumbo, - st->rx_all_count > 0 ? - st->rxerr_jumbo * 100 / st->rx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "[RX all\t%u]\n", - st->rx_all_count); - len += snprintf(buf + len, sizeof(buf) - len, "RX-all-bytes\t%u\n", - st->rx_bytes_count); - - len += snprintf(buf + len, sizeof(buf) - len, - "\nTX\n---------------------\n"); - len += snprintf(buf + len, sizeof(buf) - len, "retry\t%u\t(%u%%)\n", - st->txerr_retry, - st->tx_all_count > 0 ? - st->txerr_retry * 100 / st->tx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "FIFO\t%u\t(%u%%)\n", - st->txerr_fifo, - st->tx_all_count > 0 ? - st->txerr_fifo * 100 / st->tx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "filter\t%u\t(%u%%)\n", - st->txerr_filt, - st->tx_all_count > 0 ? - st->txerr_filt * 100 / st->tx_all_count : 0); - len += snprintf(buf + len, sizeof(buf) - len, "[TX all\t%u]\n", - st->tx_all_count); - len += snprintf(buf + len, sizeof(buf) - len, "TX-all-bytes\t%u\n", - st->tx_bytes_count); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_frameerrors(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - struct ath5k_statistics *st = &ah->stats; - char buf[20]; - - if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) - return -EFAULT; - - if (strncmp(buf, "clear", 5) == 0) { - st->rxerr_crc = 0; - st->rxerr_phy = 0; - st->rxerr_fifo = 0; - st->rxerr_decrypt = 0; - st->rxerr_mic = 0; - st->rxerr_proc = 0; - st->rxerr_jumbo = 0; - st->rx_all_count = 0; - st->txerr_retry = 0; - st->txerr_fifo = 0; - st->txerr_filt = 0; - st->tx_all_count = 0; - printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n"); - } - return count; -} - -static const struct file_operations fops_frameerrors = { - .read = read_file_frameerrors, - .write = write_file_frameerrors, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - - -/* debugfs: ani */ - -static ssize_t read_file_ani(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - struct ath5k_statistics *st = &ah->stats; - struct ath5k_ani_state *as = &ah->ani_state; - - char buf[700]; - unsigned int len = 0; - - len += snprintf(buf + len, sizeof(buf) - len, - "HW has PHY error counters:\t%s\n", - ah->ah_capabilities.cap_has_phyerr_counters ? - "yes" : "no"); - len += snprintf(buf + len, sizeof(buf) - len, - "HW max spur immunity level:\t%d\n", - as->max_spur_level); - len += snprintf(buf + len, sizeof(buf) - len, - "\nANI state\n--------------------------------------------\n"); - len += snprintf(buf + len, sizeof(buf) - len, "operating mode:\t\t\t"); - switch (as->ani_mode) { - case ATH5K_ANI_MODE_OFF: - len += snprintf(buf + len, sizeof(buf) - len, "OFF\n"); - break; - case ATH5K_ANI_MODE_MANUAL_LOW: - len += snprintf(buf + len, sizeof(buf) - len, - "MANUAL LOW\n"); - break; - case ATH5K_ANI_MODE_MANUAL_HIGH: - len += snprintf(buf + len, sizeof(buf) - len, - "MANUAL HIGH\n"); - break; - case ATH5K_ANI_MODE_AUTO: - len += snprintf(buf + len, sizeof(buf) - len, "AUTO\n"); - break; - default: - len += snprintf(buf + len, sizeof(buf) - len, - "??? (not good)\n"); - break; - } - len += snprintf(buf + len, sizeof(buf) - len, - "noise immunity level:\t\t%d\n", - as->noise_imm_level); - len += snprintf(buf + len, sizeof(buf) - len, - "spur immunity level:\t\t%d\n", - as->spur_level); - len += snprintf(buf + len, sizeof(buf) - len, - "firstep level:\t\t\t%d\n", - as->firstep_level); - len += snprintf(buf + len, sizeof(buf) - len, - "OFDM weak signal detection:\t%s\n", - as->ofdm_weak_sig ? "on" : "off"); - len += snprintf(buf + len, sizeof(buf) - len, - "CCK weak signal detection:\t%s\n", - as->cck_weak_sig ? "on" : "off"); - - len += snprintf(buf + len, sizeof(buf) - len, - "\nMIB INTERRUPTS:\t\t%u\n", - st->mib_intr); - len += snprintf(buf + len, sizeof(buf) - len, - "beacon RSSI average:\t%d\n", - (int)ewma_read(&ah->ah_beacon_rssi_avg)); - -#define CC_PRINT(_struct, _field) \ - _struct._field, \ - _struct.cycles > 0 ? \ - _struct._field * 100 / _struct.cycles : 0 - - len += snprintf(buf + len, sizeof(buf) - len, - "profcnt tx\t\t%u\t(%d%%)\n", - CC_PRINT(as->last_cc, tx_frame)); - len += snprintf(buf + len, sizeof(buf) - len, - "profcnt rx\t\t%u\t(%d%%)\n", - CC_PRINT(as->last_cc, rx_frame)); - len += snprintf(buf + len, sizeof(buf) - len, - "profcnt busy\t\t%u\t(%d%%)\n", - CC_PRINT(as->last_cc, rx_busy)); -#undef CC_PRINT - len += snprintf(buf + len, sizeof(buf) - len, "profcnt cycles\t\t%u\n", - as->last_cc.cycles); - len += snprintf(buf + len, sizeof(buf) - len, - "listen time\t\t%d\tlast: %d\n", - as->listen_time, as->last_listen); - len += snprintf(buf + len, sizeof(buf) - len, - "OFDM errors\t\t%u\tlast: %u\tsum: %u\n", - as->ofdm_errors, as->last_ofdm_errors, - as->sum_ofdm_errors); - len += snprintf(buf + len, sizeof(buf) - len, - "CCK errors\t\t%u\tlast: %u\tsum: %u\n", - as->cck_errors, as->last_cck_errors, - as->sum_cck_errors); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_PHYERR_CNT1\t%x\t(=%d)\n", - ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1), - ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - - ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1))); - len += snprintf(buf + len, sizeof(buf) - len, - "AR5K_PHYERR_CNT2\t%x\t(=%d)\n", - ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2), - ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - - ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2))); - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_ani(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[20]; - - if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) - return -EFAULT; - - if (strncmp(buf, "sens-low", 8) == 0) { - ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_HIGH); - } else if (strncmp(buf, "sens-high", 9) == 0) { - ath5k_ani_init(ah, ATH5K_ANI_MODE_MANUAL_LOW); - } else if (strncmp(buf, "ani-off", 7) == 0) { - ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF); - } else if (strncmp(buf, "ani-on", 6) == 0) { - ath5k_ani_init(ah, ATH5K_ANI_MODE_AUTO); - } else if (strncmp(buf, "noise-low", 9) == 0) { - ath5k_ani_set_noise_immunity_level(ah, 0); - } else if (strncmp(buf, "noise-high", 10) == 0) { - ath5k_ani_set_noise_immunity_level(ah, - ATH5K_ANI_MAX_NOISE_IMM_LVL); - } else if (strncmp(buf, "spur-low", 8) == 0) { - ath5k_ani_set_spur_immunity_level(ah, 0); - } else if (strncmp(buf, "spur-high", 9) == 0) { - ath5k_ani_set_spur_immunity_level(ah, - ah->ani_state.max_spur_level); - } else if (strncmp(buf, "fir-low", 7) == 0) { - ath5k_ani_set_firstep_level(ah, 0); - } else if (strncmp(buf, "fir-high", 8) == 0) { - ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL); - } else if (strncmp(buf, "ofdm-off", 8) == 0) { - ath5k_ani_set_ofdm_weak_signal_detection(ah, false); - } else if (strncmp(buf, "ofdm-on", 7) == 0) { - ath5k_ani_set_ofdm_weak_signal_detection(ah, true); - } else if (strncmp(buf, "cck-off", 7) == 0) { - ath5k_ani_set_cck_weak_signal_detection(ah, false); - } else if (strncmp(buf, "cck-on", 6) == 0) { - ath5k_ani_set_cck_weak_signal_detection(ah, true); - } - return count; -} - -static const struct file_operations fops_ani = { - .read = read_file_ani, - .write = write_file_ani, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - - -/* debugfs: queues etc */ - -static ssize_t read_file_queue(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[700]; - unsigned int len = 0; - - struct ath5k_txq *txq; - struct ath5k_buf *bf, *bf0; - int i, n; - - len += snprintf(buf + len, sizeof(buf) - len, - "available txbuffers: %d\n", ah->txbuf_len); - - for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) { - txq = &ah->txqs[i]; - - len += snprintf(buf + len, sizeof(buf) - len, - "%02d: %ssetup\n", i, txq->setup ? "" : "not "); - - if (!txq->setup) - continue; - - n = 0; - spin_lock_bh(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) - n++; - spin_unlock_bh(&txq->lock); - - len += snprintf(buf + len, sizeof(buf) - len, - " len: %d bufs: %d\n", txq->txq_len, n); - len += snprintf(buf + len, sizeof(buf) - len, - " stuck: %d\n", txq->txq_stuck); - } - - if (len > sizeof(buf)) - len = sizeof(buf); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_queue(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct ath5k_hw *ah = file->private_data; - char buf[20]; - - if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) - return -EFAULT; - - if (strncmp(buf, "start", 5) == 0) - ieee80211_wake_queues(ah->hw); - else if (strncmp(buf, "stop", 4) == 0) - ieee80211_stop_queues(ah->hw); - - return count; -} - - -static const struct file_operations fops_queue = { - .read = read_file_queue, - .write = write_file_queue, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - - -void -ath5k_debug_init_device(struct ath5k_hw *ah) -{ - struct dentry *phydir; - - ah->debug.level = ath5k_debug; - - phydir = debugfs_create_dir("ath5k", ah->hw->wiphy->debugfsdir); - if (!phydir) - return; - - debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, ah, - &fops_debug); - - debugfs_create_file("registers", S_IRUSR, phydir, ah, &fops_registers); - - debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah, - &fops_beacon); - - debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset); - - debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah, - &fops_antenna); - - debugfs_create_file("misc", S_IRUSR, phydir, ah, &fops_misc); - - debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, ah, - &fops_frameerrors); - - debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, ah, &fops_ani); - - debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, ah, - &fops_queue); - - debugfs_create_bool("32khz_clock", S_IWUSR | S_IRUSR, phydir, - &ah->ah_use_32khz_clock); -} - -/* functions used in other places */ - -void -ath5k_debug_dump_bands(struct ath5k_hw *ah) -{ - unsigned int b, i; - - if (likely(!(ah->debug.level & ATH5K_DEBUG_DUMPBANDS))) - return; - - BUG_ON(!ah->sbands); - - for (b = 0; b < IEEE80211_NUM_BANDS; b++) { - struct ieee80211_supported_band *band = &ah->sbands[b]; - char bname[6]; - switch (band->band) { - case IEEE80211_BAND_2GHZ: - strcpy(bname, "2 GHz"); - break; - case IEEE80211_BAND_5GHZ: - strcpy(bname, "5 GHz"); - break; - default: - printk(KERN_DEBUG "Band not supported: %d\n", - band->band); - return; - } - printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname, - band->n_channels, band->n_bitrates); - printk(KERN_DEBUG " channels:\n"); - for (i = 0; i < band->n_channels; i++) - printk(KERN_DEBUG " %3d %d %.4x %.4x\n", - ieee80211_frequency_to_channel( - band->channels[i].center_freq), - band->channels[i].center_freq, - band->channels[i].hw_value, - band->channels[i].flags); - printk(KERN_DEBUG " rates:\n"); - for (i = 0; i < band->n_bitrates; i++) - printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n", - band->bitrates[i].bitrate, - band->bitrates[i].hw_value, - band->bitrates[i].flags, - band->bitrates[i].hw_value_short); - } -} - -static inline void -ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done, - struct ath5k_rx_status *rs) -{ - struct ath5k_desc *ds = bf->desc; - struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx; - - printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n", - ds, (unsigned long long)bf->daddr, - ds->ds_link, ds->ds_data, - rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1, - rd->rx_stat.rx_status_0, rd->rx_stat.rx_status_1, - !done ? ' ' : (rs->rs_status == 0) ? '*' : '!'); -} - -void -ath5k_debug_printrxbuffs(struct ath5k_hw *ah) -{ - struct ath5k_desc *ds; - struct ath5k_buf *bf; - struct ath5k_rx_status rs = {}; - int status; - - if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC))) - return; - - printk(KERN_DEBUG "rxdp %x, rxlink %p\n", - ath5k_hw_get_rxdp(ah), ah->rxlink); - - spin_lock_bh(&ah->rxbuflock); - list_for_each_entry(bf, &ah->rxbuf, list) { - ds = bf->desc; - status = ah->ah_proc_rx_desc(ah, ds, &rs); - if (!status) - ath5k_debug_printrxbuf(bf, status == 0, &rs); - } - spin_unlock_bh(&ah->rxbuflock); -} - -void -ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf) -{ - struct ath5k_desc *ds = bf->desc; - struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212; - struct ath5k_tx_status ts = {}; - int done; - - if (likely(!(ah->debug.level & ATH5K_DEBUG_DESC))) - return; - - done = ah->ah_proc_tx_desc(ah, bf->desc, &ts); - - printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x " - "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link, - ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1, - td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3, - td->tx_stat.tx_status_0, td->tx_stat.tx_status_1, - done ? ' ' : (ts.ts_status == 0) ? '*' : '!'); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/debug.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/debug.h deleted file mode 100644 index 0a3f916a..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/debug.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com> - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file 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, see <http://www.gnu.org/licenses/>. - * - * - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2004-2005 Atheros Communications, Inc. - * Copyright (c) 2006 Devicescape Software, Inc. - * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - */ - -#ifndef _ATH5K_DEBUG_H -#define _ATH5K_DEBUG_H - -struct ath5k_hw; -struct sk_buff; -struct ath5k_buf; - -struct ath5k_dbg_info { - unsigned int level; /* debug level */ -}; - -/** - * enum ath5k_debug_level - ath5k debug level - * - * @ATH5K_DEBUG_RESET: reset processing - * @ATH5K_DEBUG_INTR: interrupt handling - * @ATH5K_DEBUG_MODE: mode init/setup - * @ATH5K_DEBUG_XMIT: basic xmit operation - * @ATH5K_DEBUG_BEACON: beacon handling - * @ATH5K_DEBUG_CALIBRATE: periodic calibration - * @ATH5K_DEBUG_TXPOWER: transmit power setting - * @ATH5K_DEBUG_LED: led management - * @ATH5K_DEBUG_DUMP_RX: print received skb content - * @ATH5K_DEBUG_DUMP_TX: print transmit skb content - * @ATH5K_DEBUG_DUMPBANDS: dump bands - * @ATH5K_DEBUG_DMA: debug dma start/stop - * @ATH5K_DEBUG_TRACE: trace function calls - * @ATH5K_DEBUG_DESC: descriptor setup - * @ATH5K_DEBUG_ANY: show at any debug level - * - * The debug level is used to control the amount and type of debugging output - * we want to see. The debug level is given in calls to ATH5K_DBG to specify - * where the message should appear, and the user can control the debugging - * messages he wants to see, either by the module parameter 'debug' on module - * load, or dynamically by using debugfs 'ath5k/phyX/debug'. these levels can - * be combined together by bitwise OR. - */ -enum ath5k_debug_level { - ATH5K_DEBUG_RESET = 0x00000001, - ATH5K_DEBUG_INTR = 0x00000002, - ATH5K_DEBUG_MODE = 0x00000004, - ATH5K_DEBUG_XMIT = 0x00000008, - ATH5K_DEBUG_BEACON = 0x00000010, - ATH5K_DEBUG_CALIBRATE = 0x00000020, - ATH5K_DEBUG_TXPOWER = 0x00000040, - ATH5K_DEBUG_LED = 0x00000080, - ATH5K_DEBUG_DUMPBANDS = 0x00000400, - ATH5K_DEBUG_DMA = 0x00000800, - ATH5K_DEBUG_ANI = 0x00002000, - ATH5K_DEBUG_DESC = 0x00004000, - ATH5K_DEBUG_ANY = 0xffffffff -}; - -#ifdef CONFIG_ATH5K_DEBUG - -#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \ - if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \ - ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \ - __func__, __LINE__, ##__VA_ARGS__); \ - } while (0) - -#define ATH5K_DBG_UNLIMIT(_sc, _m, _fmt, ...) do { \ - if (unlikely((_sc)->debug.level & (_m))) \ - ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \ - __func__, __LINE__, ##__VA_ARGS__); \ - } while (0) - -void -ath5k_debug_init_device(struct ath5k_hw *ah); - -void -ath5k_debug_printrxbuffs(struct ath5k_hw *ah); - -void -ath5k_debug_dump_bands(struct ath5k_hw *ah); - -void -ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf); - -#else /* no debugging */ - -#include <linux/compiler.h> - -static inline __printf(3, 4) void -ATH5K_DBG(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) {} - -static inline __printf(3, 4) void -ATH5K_DBG_UNLIMIT(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) -{} - -static inline void -ath5k_debug_init_device(struct ath5k_hw *ah) {} - -static inline void -ath5k_debug_printrxbuffs(struct ath5k_hw *ah) {} - -static inline void -ath5k_debug_dump_bands(struct ath5k_hw *ah) {} - -static inline void -ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf) {} - -#endif /* ifdef CONFIG_ATH5K_DEBUG */ - -#endif /* ifndef _ATH5K_DEBUG_H */ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/desc.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/desc.c deleted file mode 100644 index f8bfa3ac..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/desc.c +++ /dev/null @@ -1,788 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> - * - * Permission to use, copy, modify, and 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. - * - */ - -/******************************\ - Hardware Descriptor Functions -\******************************/ - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - - -/** - * DOC: Hardware descriptor functions - * - * Here we handle the processing of the low-level hw descriptors - * that hw reads and writes via DMA for each TX and RX attempt (that means - * we can also have descriptors for failed TX/RX tries). We have two kind of - * descriptors for RX and TX, control descriptors tell the hw how to send or - * receive a packet where to read/write it from/to etc and status descriptors - * that contain information about how the packet was sent or received (errors - * included). - * - * Descriptor format is not exactly the same for each MAC chip version so we - * have function pointers on &struct ath5k_hw we initialize at runtime based on - * the chip used. - */ - - -/************************\ -* TX Control descriptors * -\************************/ - -/** - * ath5k_hw_setup_2word_tx_desc() - Initialize a 2-word tx control descriptor - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @pkt_len: Frame length in bytes - * @hdr_len: Header length in bytes (only used on AR5210) - * @padsize: Any padding we've added to the frame length - * @type: One of enum ath5k_pkt_type - * @tx_power: Tx power in 0.5dB steps - * @tx_rate0: HW idx for transmission rate - * @tx_tries0: Max number of retransmissions - * @key_index: Index on key table to use for encryption - * @antenna_mode: Which antenna to use (0 for auto) - * @flags: One of AR5K_TXDESC_* flags (desc.h) - * @rtscts_rate: HW idx for RTS/CTS transmission rate - * @rtscts_duration: What to put on duration field on the header of RTS/CTS - * - * Internal function to initialize a 2-Word TX control descriptor - * found on AR5210 and AR5211 MACs chips. - * - * Returns 0 on success or -EINVAL on false input - */ -static int -ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, - struct ath5k_desc *desc, - unsigned int pkt_len, unsigned int hdr_len, - int padsize, - enum ath5k_pkt_type type, - unsigned int tx_power, - unsigned int tx_rate0, unsigned int tx_tries0, - unsigned int key_index, - unsigned int antenna_mode, - unsigned int flags, - unsigned int rtscts_rate, unsigned int rtscts_duration) -{ - u32 frame_type; - struct ath5k_hw_2w_tx_ctl *tx_ctl; - unsigned int frame_len; - - tx_ctl = &desc->ud.ds_tx5210.tx_ctl; - - /* - * Validate input - * - Zero retries don't make sense. - * - A zero rate will put the HW into a mode where it continuously sends - * noise on the channel, so it is important to avoid this. - */ - if (unlikely(tx_tries0 == 0)) { - ATH5K_ERR(ah, "zero retries\n"); - WARN_ON(1); - return -EINVAL; - } - if (unlikely(tx_rate0 == 0)) { - ATH5K_ERR(ah, "zero rate\n"); - WARN_ON(1); - return -EINVAL; - } - - /* Clear descriptor */ - memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc)); - - /* Setup control descriptor */ - - /* Verify and set frame length */ - - /* remove padding we might have added before */ - frame_len = pkt_len - padsize + FCS_LEN; - - if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) - return -EINVAL; - - tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; - - /* Verify and set buffer length */ - - /* NB: beacon's BufLen must be a multiple of 4 bytes */ - if (type == AR5K_PKT_TYPE_BEACON) - pkt_len = roundup(pkt_len, 4); - - if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) - return -EINVAL; - - tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; - - /* - * Verify and set header length (only 5210) - */ - if (ah->ah_version == AR5K_AR5210) { - if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210) - return -EINVAL; - tx_ctl->tx_control_0 |= - AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210); - } - - /*Differences between 5210-5211*/ - if (ah->ah_version == AR5K_AR5210) { - switch (type) { - case AR5K_PKT_TYPE_BEACON: - case AR5K_PKT_TYPE_PROBE_RESP: - frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; - break; - case AR5K_PKT_TYPE_PIFS: - frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; - break; - default: - frame_type = type; - break; - } - - tx_ctl->tx_control_0 |= - AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) | - AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); - - } else { - tx_ctl->tx_control_0 |= - AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | - AR5K_REG_SM(antenna_mode, - AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); - tx_ctl->tx_control_1 |= - AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211); - } - -#define _TX_FLAGS(_c, _flag) \ - if (flags & AR5K_TXDESC_##_flag) { \ - tx_ctl->tx_control_##_c |= \ - AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ - } -#define _TX_FLAGS_5211(_c, _flag) \ - if (flags & AR5K_TXDESC_##_flag) { \ - tx_ctl->tx_control_##_c |= \ - AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211; \ - } - _TX_FLAGS(0, CLRDMASK); - _TX_FLAGS(0, INTREQ); - _TX_FLAGS(0, RTSENA); - - if (ah->ah_version == AR5K_AR5211) { - _TX_FLAGS_5211(0, VEOL); - _TX_FLAGS_5211(1, NOACK); - } - -#undef _TX_FLAGS -#undef _TX_FLAGS_5211 - - /* - * WEP crap - */ - if (key_index != AR5K_TXKEYIX_INVALID) { - tx_ctl->tx_control_0 |= - AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - tx_ctl->tx_control_1 |= - AR5K_REG_SM(key_index, - AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX); - } - - /* - * RTS/CTS Duration [5210 ?] - */ - if ((ah->ah_version == AR5K_AR5210) && - (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) - tx_ctl->tx_control_1 |= rtscts_duration & - AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210; - - return 0; -} - -/** - * ath5k_hw_setup_4word_tx_desc() - Initialize a 4-word tx control descriptor - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @pkt_len: Frame length in bytes - * @hdr_len: Header length in bytes (only used on AR5210) - * @padsize: Any padding we've added to the frame length - * @type: One of enum ath5k_pkt_type - * @tx_power: Tx power in 0.5dB steps - * @tx_rate0: HW idx for transmission rate - * @tx_tries0: Max number of retransmissions - * @key_index: Index on key table to use for encryption - * @antenna_mode: Which antenna to use (0 for auto) - * @flags: One of AR5K_TXDESC_* flags (desc.h) - * @rtscts_rate: HW idx for RTS/CTS transmission rate - * @rtscts_duration: What to put on duration field on the header of RTS/CTS - * - * Internal function to initialize a 4-Word TX control descriptor - * found on AR5212 and later MACs chips. - * - * Returns 0 on success or -EINVAL on false input - */ -static int -ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, - struct ath5k_desc *desc, - unsigned int pkt_len, unsigned int hdr_len, - int padsize, - enum ath5k_pkt_type type, - unsigned int tx_power, - unsigned int tx_rate0, unsigned int tx_tries0, - unsigned int key_index, - unsigned int antenna_mode, - unsigned int flags, - unsigned int rtscts_rate, unsigned int rtscts_duration) -{ - struct ath5k_hw_4w_tx_ctl *tx_ctl; - unsigned int frame_len; - - /* - * Use local variables for these to reduce load/store access on - * uncached memory - */ - u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0; - - tx_ctl = &desc->ud.ds_tx5212.tx_ctl; - - /* - * Validate input - * - Zero retries don't make sense. - * - A zero rate will put the HW into a mode where it continuously sends - * noise on the channel, so it is important to avoid this. - */ - if (unlikely(tx_tries0 == 0)) { - ATH5K_ERR(ah, "zero retries\n"); - WARN_ON(1); - return -EINVAL; - } - if (unlikely(tx_rate0 == 0)) { - ATH5K_ERR(ah, "zero rate\n"); - WARN_ON(1); - return -EINVAL; - } - - tx_power += ah->ah_txpower.txp_offset; - if (tx_power > AR5K_TUNE_MAX_TXPOWER) - tx_power = AR5K_TUNE_MAX_TXPOWER; - - /* Clear descriptor status area */ - memset(&desc->ud.ds_tx5212.tx_stat, 0, - sizeof(desc->ud.ds_tx5212.tx_stat)); - - /* Setup control descriptor */ - - /* Verify and set frame length */ - - /* remove padding we might have added before */ - frame_len = pkt_len - padsize + FCS_LEN; - - if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) - return -EINVAL; - - txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; - - /* Verify and set buffer length */ - - /* NB: beacon's BufLen must be a multiple of 4 bytes */ - if (type == AR5K_PKT_TYPE_BEACON) - pkt_len = roundup(pkt_len, 4); - - if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) - return -EINVAL; - - txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; - - txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | - AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); - txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); - txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); - txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; - -#define _TX_FLAGS(_c, _flag) \ - if (flags & AR5K_TXDESC_##_flag) { \ - txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ - } - - _TX_FLAGS(0, CLRDMASK); - _TX_FLAGS(0, VEOL); - _TX_FLAGS(0, INTREQ); - _TX_FLAGS(0, RTSENA); - _TX_FLAGS(0, CTSENA); - _TX_FLAGS(1, NOACK); - -#undef _TX_FLAGS - - /* - * WEP crap - */ - if (key_index != AR5K_TXKEYIX_INVALID) { - txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; - txctl1 |= AR5K_REG_SM(key_index, - AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX); - } - - /* - * RTS/CTS - */ - if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { - if ((flags & AR5K_TXDESC_RTSENA) && - (flags & AR5K_TXDESC_CTSENA)) - return -EINVAL; - txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION; - txctl3 |= AR5K_REG_SM(rtscts_rate, - AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); - } - - tx_ctl->tx_control_0 = txctl0; - tx_ctl->tx_control_1 = txctl1; - tx_ctl->tx_control_2 = txctl2; - tx_ctl->tx_control_3 = txctl3; - - return 0; -} - -/** - * ath5k_hw_setup_mrr_tx_desc() - Initialize an MRR tx control descriptor - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @tx_rate1: HW idx for rate used on transmission series 1 - * @tx_tries1: Max number of retransmissions for transmission series 1 - * @tx_rate2: HW idx for rate used on transmission series 2 - * @tx_tries2: Max number of retransmissions for transmission series 2 - * @tx_rate3: HW idx for rate used on transmission series 3 - * @tx_tries3: Max number of retransmissions for transmission series 3 - * - * Multi rate retry (MRR) tx control descriptors are available only on AR5212 - * MACs, they are part of the normal 4-word tx control descriptor (see above) - * but we handle them through a separate function for better abstraction. - * - * Returns 0 on success or -EINVAL on invalid input - */ -int -ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, - struct ath5k_desc *desc, - u_int tx_rate1, u_int tx_tries1, - u_int tx_rate2, u_int tx_tries2, - u_int tx_rate3, u_int tx_tries3) -{ - struct ath5k_hw_4w_tx_ctl *tx_ctl; - - /* no mrr support for cards older than 5212 */ - if (ah->ah_version < AR5K_AR5212) - return 0; - - /* - * Rates can be 0 as long as the retry count is 0 too. - * A zero rate and nonzero retry count will put the HW into a mode where - * it continuously sends noise on the channel, so it is important to - * avoid this. - */ - if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || - (tx_rate2 == 0 && tx_tries2 != 0) || - (tx_rate3 == 0 && tx_tries3 != 0))) { - ATH5K_ERR(ah, "zero rate\n"); - WARN_ON(1); - return -EINVAL; - } - - if (ah->ah_version == AR5K_AR5212) { - tx_ctl = &desc->ud.ds_tx5212.tx_ctl; - -#define _XTX_TRIES(_n) \ - if (tx_tries##_n) { \ - tx_ctl->tx_control_2 |= \ - AR5K_REG_SM(tx_tries##_n, \ - AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ - tx_ctl->tx_control_3 |= \ - AR5K_REG_SM(tx_rate##_n, \ - AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ - } - - _XTX_TRIES(1); - _XTX_TRIES(2); - _XTX_TRIES(3); - -#undef _XTX_TRIES - - return 1; - } - - return 0; -} - - -/***********************\ -* TX Status descriptors * -\***********************/ - -/** - * ath5k_hw_proc_2word_tx_status() - Process a tx status descriptor on 5210/1 - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @ts: The &struct ath5k_tx_status - */ -static int -ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc, - struct ath5k_tx_status *ts) -{ - struct ath5k_hw_2w_tx_ctl *tx_ctl; - struct ath5k_hw_tx_status *tx_status; - - tx_ctl = &desc->ud.ds_tx5210.tx_ctl; - tx_status = &desc->ud.ds_tx5210.tx_stat; - - /* No frame has been send or error */ - if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) - return -EINPROGRESS; - - /* - * Get descriptor status - */ - ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0, - AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - /*TODO: ts->ts_virtcol + test*/ - ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_SEQ_NUM); - ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, - AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); - ts->ts_antenna = 1; - ts->ts_status = 0; - ts->ts_final_idx = 0; - - if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { - if (tx_status->tx_status_0 & - AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) - ts->ts_status |= AR5K_TXERR_XRETRY; - - if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) - ts->ts_status |= AR5K_TXERR_FIFO; - - if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) - ts->ts_status |= AR5K_TXERR_FILT; - } - - return 0; -} - -/** - * ath5k_hw_proc_4word_tx_status() - Process a tx status descriptor on 5212 - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @ts: The &struct ath5k_tx_status - */ -static int -ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc, - struct ath5k_tx_status *ts) -{ - struct ath5k_hw_4w_tx_ctl *tx_ctl; - struct ath5k_hw_tx_status *tx_status; - u32 txstat0, txstat1; - - tx_ctl = &desc->ud.ds_tx5212.tx_ctl; - tx_status = &desc->ud.ds_tx5212.tx_stat; - - txstat1 = ACCESS_ONCE(tx_status->tx_status_1); - - /* No frame has been send or error */ - if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE))) - return -EINPROGRESS; - - txstat0 = ACCESS_ONCE(tx_status->tx_status_0); - - /* - * Get descriptor status - */ - ts->ts_tstamp = AR5K_REG_MS(txstat0, - AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); - ts->ts_shortretry = AR5K_REG_MS(txstat0, - AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); - ts->ts_final_retry = AR5K_REG_MS(txstat0, - AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); - ts->ts_seqnum = AR5K_REG_MS(txstat1, - AR5K_DESC_TX_STATUS1_SEQ_NUM); - ts->ts_rssi = AR5K_REG_MS(txstat1, - AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); - ts->ts_antenna = (txstat1 & - AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1; - ts->ts_status = 0; - - ts->ts_final_idx = AR5K_REG_MS(txstat1, - AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212); - - /* TX error */ - if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { - if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) - ts->ts_status |= AR5K_TXERR_XRETRY; - - if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) - ts->ts_status |= AR5K_TXERR_FIFO; - - if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED) - ts->ts_status |= AR5K_TXERR_FILT; - } - - return 0; -} - - -/****************\ -* RX Descriptors * -\****************/ - -/** - * ath5k_hw_setup_rx_desc() - Initialize an rx control descriptor - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @size: RX buffer length in bytes - * @flags: One of AR5K_RXDESC_* flags - */ -int -ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, - struct ath5k_desc *desc, - u32 size, unsigned int flags) -{ - struct ath5k_hw_rx_ctl *rx_ctl; - - rx_ctl = &desc->ud.ds_rx.rx_ctl; - - /* - * Clear the descriptor - * If we don't clean the status descriptor, - * while scanning we get too many results, - * most of them virtual, after some secs - * of scanning system hangs. M.F. - */ - memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); - - if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN)) - return -EINVAL; - - /* Setup descriptor */ - rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; - - if (flags & AR5K_RXDESC_INTREQ) - rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; - - return 0; -} - -/** - * ath5k_hw_proc_5210_rx_status() - Process the rx status descriptor on 5210/1 - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @rs: The &struct ath5k_rx_status - * - * Internal function used to process an RX status descriptor - * on AR5210/5211 MAC. - * - * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e - * frame yet. - */ -static int -ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc, - struct ath5k_rx_status *rs) -{ - struct ath5k_hw_rx_status *rx_status; - - rx_status = &desc->ud.ds_rx.rx_stat; - - /* No frame received / not ready */ - if (unlikely(!(rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_DONE))) - return -EINPROGRESS; - - memset(rs, 0, sizeof(struct ath5k_rx_status)); - - /* - * Frame receive status - */ - rs->rs_datalen = rx_status->rx_status_0 & - AR5K_5210_RX_DESC_STATUS0_DATA_LEN; - rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); - rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); - rs->rs_more = !!(rx_status->rx_status_0 & - AR5K_5210_RX_DESC_STATUS0_MORE); - /* TODO: this timestamp is 13 bit, later on we assume 15 bit! - * also the HAL code for 5210 says the timestamp is bits [10..22] of the - * TSF, and extends the timestamp here to 15 bit. - * we need to check on 5210... - */ - rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); - - if (ah->ah_version == AR5K_AR5211) - rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, - AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211); - else - rs->rs_antenna = (rx_status->rx_status_0 & - AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210) - ? 2 : 1; - - /* - * Key table status - */ - if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID) - rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_5210_RX_DESC_STATUS1_KEY_INDEX); - else - rs->rs_keyix = AR5K_RXKEYIX_INVALID; - - /* - * Receive/descriptor errors - */ - if (!(rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { - if (rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) - rs->rs_status |= AR5K_RXERR_CRC; - - /* only on 5210 */ - if ((ah->ah_version == AR5K_AR5210) && - (rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210)) - rs->rs_status |= AR5K_RXERR_FIFO; - - if (rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { - rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, - AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); - } - - if (rx_status->rx_status_1 & - AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) - rs->rs_status |= AR5K_RXERR_DECRYPT; - } - - return 0; -} - -/** - * ath5k_hw_proc_5212_rx_status() - Process the rx status descriptor on 5212 - * @ah: The &struct ath5k_hw - * @desc: The &struct ath5k_desc - * @rs: The &struct ath5k_rx_status - * - * Internal function used to process an RX status descriptor - * on AR5212 and later MAC. - * - * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e - * frame yet. - */ -static int -ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, - struct ath5k_desc *desc, - struct ath5k_rx_status *rs) -{ - struct ath5k_hw_rx_status *rx_status; - u32 rxstat0, rxstat1; - - rx_status = &desc->ud.ds_rx.rx_stat; - rxstat1 = ACCESS_ONCE(rx_status->rx_status_1); - - /* No frame received / not ready */ - if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE))) - return -EINPROGRESS; - - memset(rs, 0, sizeof(struct ath5k_rx_status)); - rxstat0 = ACCESS_ONCE(rx_status->rx_status_0); - - /* - * Frame receive status - */ - rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN; - rs->rs_rssi = AR5K_REG_MS(rxstat0, - AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); - rs->rs_rate = AR5K_REG_MS(rxstat0, - AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); - rs->rs_antenna = AR5K_REG_MS(rxstat0, - AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); - rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE); - rs->rs_tstamp = AR5K_REG_MS(rxstat1, - AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); - - /* - * Key table status - */ - if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) - rs->rs_keyix = AR5K_REG_MS(rxstat1, - AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); - else - rs->rs_keyix = AR5K_RXKEYIX_INVALID; - - /* - * Receive/descriptor errors - */ - if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { - if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) - rs->rs_status |= AR5K_RXERR_CRC; - - if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { - rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr = AR5K_REG_MS(rxstat1, - AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); - if (!ah->ah_capabilities.cap_has_phyerr_counters) - ath5k_ani_phy_error_report(ah, rs->rs_phyerr); - } - - if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) - rs->rs_status |= AR5K_RXERR_DECRYPT; - - if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) - rs->rs_status |= AR5K_RXERR_MIC; - } - return 0; -} - - -/********\ -* Attach * -\********/ - -/** - * ath5k_hw_init_desc_functions() - Init function pointers inside ah - * @ah: The &struct ath5k_hw - * - * Maps the internal descriptor functions to the function pointers on ah, used - * from above. This is used as an abstraction layer to handle the various chips - * the same way. - */ -int -ath5k_hw_init_desc_functions(struct ath5k_hw *ah) -{ - if (ah->ah_version == AR5K_AR5212) { - ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; - ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; - ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; - } else if (ah->ah_version <= AR5K_AR5211) { - ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; - ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; - ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; - } else - return -ENOTSUPP; - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/desc.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/desc.h deleted file mode 100644 index 8d6c01a4..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/desc.h +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/* - * RX/TX descriptor structures - */ - -/** - * struct ath5k_hw_rx_ctl - Common hardware RX control descriptor - * @rx_control_0: RX control word 0 - * @rx_control_1: RX control word 1 - */ -struct ath5k_hw_rx_ctl { - u32 rx_control_0; - u32 rx_control_1; -} __packed __aligned(4); - -/* RX control word 1 fields/flags */ -#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff /* data buffer length */ -#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 /* RX interrupt request */ - -/** - * struct ath5k_hw_rx_status - Common hardware RX status descriptor - * @rx_status_0: RX status word 0 - * @rx_status_1: RX status word 1 - * - * 5210, 5211 and 5212 differ only in the fields and flags defined below - */ -struct ath5k_hw_rx_status { - u32 rx_status_0; - u32 rx_status_1; -} __packed __aligned(4); - -/* 5210/5211 */ -/* RX status word 0 fields/flags */ -#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff /* RX data length */ -#define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 /* more desc for this frame */ -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210 0x00004000 /* [5210] receive on ant 1 */ -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 /* reception rate */ -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S 15 -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000 /* rssi */ -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211 0x38000000 /* [5211] receive antenna */ -#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211_S 27 - -/* RX status word 1 fields/flags */ -#define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 /* descriptor complete */ -#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* reception success */ -#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */ -#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210 0x00000008 /* [5210] FIFO overrun */ -#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010 /* decryption CRC failure */ -#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR 0x000000e0 /* PHY error */ -#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S 5 -#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */ -#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX 0x00007e00 /* decryption key index */ -#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S 9 -#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000 /* 13 bit of TSF */ -#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15 -#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 /* key cache miss */ - -/* 5212 */ -/* RX status word 0 fields/flags */ -#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff /* RX data length */ -#define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 /* more desc for this frame */ -#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 /* decompression CRC error */ -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000 /* reception rate */ -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S 15 -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000 /* rssi */ -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 /* receive antenna */ -#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 - -/* RX status word 1 fields/flags */ -#define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 /* descriptor complete */ -#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 /* frame reception success */ -#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 /* CRC error */ -#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008 /* decryption CRC failure */ -#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR 0x00000010 /* PHY error */ -#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR 0x00000020 /* MIC decrypt error */ -#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100 /* key index valid */ -#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00 /* decryption key index */ -#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S 9 -#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000 /* first 15bit of the TSF */ -#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16 -#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000 /* key cache miss */ -#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE 0x0000ff00 /* phy error code overlays key index and valid fields */ -#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE_S 8 - -/** - * enum ath5k_phy_error_code - PHY Error codes - * @AR5K_RX_PHY_ERROR_UNDERRUN: Transmit underrun, [5210] No error - * @AR5K_RX_PHY_ERROR_TIMING: Timing error - * @AR5K_RX_PHY_ERROR_PARITY: Illegal parity - * @AR5K_RX_PHY_ERROR_RATE: Illegal rate - * @AR5K_RX_PHY_ERROR_LENGTH: Illegal length - * @AR5K_RX_PHY_ERROR_RADAR: Radar detect, [5210] 64 QAM rate - * @AR5K_RX_PHY_ERROR_SERVICE: Illegal service - * @AR5K_RX_PHY_ERROR_TOR: Transmit override receive - * @AR5K_RX_PHY_ERROR_OFDM_TIMING: OFDM Timing error [5212+] - * @AR5K_RX_PHY_ERROR_OFDM_SIGNAL_PARITY: OFDM Signal parity error [5212+] - * @AR5K_RX_PHY_ERROR_OFDM_RATE_ILLEGAL: OFDM Illegal rate [5212+] - * @AR5K_RX_PHY_ERROR_OFDM_LENGTH_ILLEGAL: OFDM Illegal length [5212+] - * @AR5K_RX_PHY_ERROR_OFDM_POWER_DROP: OFDM Power drop [5212+] - * @AR5K_RX_PHY_ERROR_OFDM_SERVICE: OFDM Service (?) [5212+] - * @AR5K_RX_PHY_ERROR_OFDM_RESTART: OFDM Restart (?) [5212+] - * @AR5K_RX_PHY_ERROR_CCK_TIMING: CCK Timing error [5212+] - * @AR5K_RX_PHY_ERROR_CCK_HEADER_CRC: Header CRC error [5212+] - * @AR5K_RX_PHY_ERROR_CCK_RATE_ILLEGAL: Illegal rate [5212+] - * @AR5K_RX_PHY_ERROR_CCK_SERVICE: CCK Service (?) [5212+] - * @AR5K_RX_PHY_ERROR_CCK_RESTART: CCK Restart (?) [5212+] - */ -enum ath5k_phy_error_code { - AR5K_RX_PHY_ERROR_UNDERRUN = 0, - AR5K_RX_PHY_ERROR_TIMING = 1, - AR5K_RX_PHY_ERROR_PARITY = 2, - AR5K_RX_PHY_ERROR_RATE = 3, - AR5K_RX_PHY_ERROR_LENGTH = 4, - AR5K_RX_PHY_ERROR_RADAR = 5, - AR5K_RX_PHY_ERROR_SERVICE = 6, - AR5K_RX_PHY_ERROR_TOR = 7, - AR5K_RX_PHY_ERROR_OFDM_TIMING = 17, - AR5K_RX_PHY_ERROR_OFDM_SIGNAL_PARITY = 18, - AR5K_RX_PHY_ERROR_OFDM_RATE_ILLEGAL = 19, - AR5K_RX_PHY_ERROR_OFDM_LENGTH_ILLEGAL = 20, - AR5K_RX_PHY_ERROR_OFDM_POWER_DROP = 21, - AR5K_RX_PHY_ERROR_OFDM_SERVICE = 22, - AR5K_RX_PHY_ERROR_OFDM_RESTART = 23, - AR5K_RX_PHY_ERROR_CCK_TIMING = 25, - AR5K_RX_PHY_ERROR_CCK_HEADER_CRC = 26, - AR5K_RX_PHY_ERROR_CCK_RATE_ILLEGAL = 27, - AR5K_RX_PHY_ERROR_CCK_SERVICE = 30, - AR5K_RX_PHY_ERROR_CCK_RESTART = 31, -}; - -/** - * struct ath5k_hw_2w_tx_ctl - 5210/5211 hardware 2-word TX control descriptor - * @tx_control_0: TX control word 0 - * @tx_control_1: TX control word 1 - */ -struct ath5k_hw_2w_tx_ctl { - u32 tx_control_0; - u32 tx_control_1; -} __packed __aligned(4); - -/* TX control word 0 fields/flags */ -#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ -#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210 0x0003f000 /* [5210] header length */ -#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210_S 12 -#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000 /* tx rate */ -#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18 -#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000 /* RTS/CTS enable */ -#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET_5210 0x00800000 /* [5210] long packet */ -#define AR5K_2W_TX_DESC_CTL0_VEOL_5211 0x00800000 /* [5211] virtual end-of-list */ -#define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000 /* clear destination mask */ -#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 /* [5210] antenna selection */ -#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 /* [5211] antenna selection */ -#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \ - (ah->ah_version == AR5K_AR5210 ? \ - AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ - AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) -#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 -#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210 0x1c000000 /* [5210] frame type */ -#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210_S 26 -#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 /* TX interrupt request */ -#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* key is valid */ - -/* TX control word 1 fields/flags */ -#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff /* data buffer length */ -#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 /* more desc for this frame */ -#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5210 0x0007e000 /* [5210] key table index */ -#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5211 0x000fe000 /* [5211] key table index */ -#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX \ - (ah->ah_version == AR5K_AR5210 ? \ - AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5210 : \ - AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_5211) -#define AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX_S 13 -#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211 0x00700000 /* [5211] frame type */ -#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211_S 20 -#define AR5K_2W_TX_DESC_CTL1_NOACK_5211 0x00800000 /* [5211] no ACK */ -#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210 0xfff80000 /* [5210] lower 13 bit of duration */ - -/* Frame types */ -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 1 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 2 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 3 -#define AR5K_AR5211_TX_DESC_FRAME_TYPE_BEACON 3 -#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 4 -#define AR5K_AR5211_TX_DESC_FRAME_TYPE_PRESP 4 - -/** - * struct ath5k_hw_4w_tx_ctl - 5212 hardware 4-word TX control descriptor - * @tx_control_0: TX control word 0 - * @tx_control_1: TX control word 1 - * @tx_control_2: TX control word 2 - * @tx_control_3: TX control word 3 - */ -struct ath5k_hw_4w_tx_ctl { - u32 tx_control_0; - u32 tx_control_1; - u32 tx_control_2; - u32 tx_control_3; -} __packed __aligned(4); - -/* TX control word 0 fields/flags */ -#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff /* frame length */ -#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000 /* transmit power */ -#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S 16 -#define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000 /* RTS/CTS enable */ -#define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000 /* virtual end-of-list */ -#define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000 /* clear destination mask */ -#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000 /* TX antenna selection */ -#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 -#define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000 /* TX interrupt request */ -#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 /* destination index valid */ -#define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000 /* precede frame with CTS */ - -/* TX control word 1 fields/flags */ -#define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff /* data buffer length */ -#define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000 /* more desc for this frame */ -#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX 0x000fe000 /* destination table index */ -#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX_S 13 -#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000 /* frame type */ -#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S 20 -#define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000 /* no ACK */ -#define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000 /* compression processing */ -#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S 25 -#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000 /* length of frame IV */ -#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S 27 -#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000 /* length of frame ICV */ -#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S 29 - -/* TX control word 2 fields/flags */ -#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff /* RTS/CTS duration */ -#define AR5K_4W_TX_DESC_CTL2_DURATION_UPD_EN 0x00008000 /* frame duration update */ -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000 /* series 0 max attempts */ -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000 /* series 1 max attempts */ -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000 /* series 2 max attempts */ -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24 -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000 /* series 3 max attempts */ -#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28 - -/* TX control word 3 fields/flags */ -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f /* series 0 tx rate */ -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0 /* series 1 tx rate */ -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S 5 -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00 /* series 2 tx rate */ -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S 10 -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000 /* series 3 tx rate */ -#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S 15 -#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000 /* RTS or CTS rate */ -#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S 20 - -/** - * struct ath5k_hw_tx_status - Common TX status descriptor - * @tx_status_0: TX status word 0 - * @tx_status_1: TX status word 1 - */ -struct ath5k_hw_tx_status { - u32 tx_status_0; - u32 tx_status_1; -} __packed __aligned(4); - -/* TX status word 0 fields/flags */ -#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 /* TX success */ -#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 /* excessive retries */ -#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 /* FIFO underrun */ -#define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008 /* TX filter indication */ -/* according to the HAL sources the spec has short/long retry counts reversed. - * we have it reversed to the HAL sources as well, for 5210 and 5211. - * For 5212 these fields are defined as RTS_FAIL_COUNT and DATA_FAIL_COUNT, - * but used respectively as SHORT and LONG retry count in the code later. This - * is consistent with the definitions here... TODO: check */ -#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0 /* short retry count */ -#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S 4 -#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00 /* long retry count */ -#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S 8 -#define AR5K_DESC_TX_STATUS0_VIRTCOLL_CT_5211 0x0000f000 /* [5211+] virtual collision count */ -#define AR5K_DESC_TX_STATUS0_VIRTCOLL_CT_5212_S 12 -#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 /* TX timestamp */ -#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 - -/* TX status word 1 fields/flags */ -#define AR5K_DESC_TX_STATUS1_DONE 0x00000001 /* descriptor complete */ -#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe /* TX sequence number */ -#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 -#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000 /* signal strength of ACK */ -#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S 13 -#define AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212 0x00600000 /* [5212] final TX attempt series ix */ -#define AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212_S 21 -#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS_5212 0x00800000 /* [5212] compression status */ -#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212 0x01000000 /* [5212] transmit antenna */ - -/** - * struct ath5k_hw_5210_tx_desc - 5210/5211 hardware TX descriptor - * @tx_ctl: The &struct ath5k_hw_2w_tx_ctl - * @tx_stat: The &struct ath5k_hw_tx_status - */ -struct ath5k_hw_5210_tx_desc { - struct ath5k_hw_2w_tx_ctl tx_ctl; - struct ath5k_hw_tx_status tx_stat; -} __packed __aligned(4); - -/** - * struct ath5k_hw_5212_tx_desc - 5212 hardware TX descriptor - * @tx_ctl: The &struct ath5k_hw_4w_tx_ctl - * @tx_stat: The &struct ath5k_hw_tx_status - */ -struct ath5k_hw_5212_tx_desc { - struct ath5k_hw_4w_tx_ctl tx_ctl; - struct ath5k_hw_tx_status tx_stat; -} __packed __aligned(4); - -/** - * struct ath5k_hw_all_rx_desc - Common hardware RX descriptor - * @rx_ctl: The &struct ath5k_hw_rx_ctl - * @rx_stat: The &struct ath5k_hw_rx_status - */ -struct ath5k_hw_all_rx_desc { - struct ath5k_hw_rx_ctl rx_ctl; - struct ath5k_hw_rx_status rx_stat; -} __packed __aligned(4); - -/** - * struct ath5k_desc - Atheros hardware DMA descriptor - * @ds_link: Physical address of the next descriptor - * @ds_data: Physical address of data buffer (skb) - * @ud: Union containing hw_5xxx_tx_desc structs and hw_all_rx_desc - * - * This is read and written to by the hardware - */ -struct ath5k_desc { - u32 ds_link; - u32 ds_data; - - union { - struct ath5k_hw_5210_tx_desc ds_tx5210; - struct ath5k_hw_5212_tx_desc ds_tx5212; - struct ath5k_hw_all_rx_desc ds_rx; - } ud; -} __packed __aligned(4); - -#define AR5K_RXDESC_INTREQ 0x0020 - -#define AR5K_TXDESC_CLRDMASK 0x0001 -#define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/ -#define AR5K_TXDESC_RTSENA 0x0004 -#define AR5K_TXDESC_CTSENA 0x0008 -#define AR5K_TXDESC_INTREQ 0x0010 -#define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/ diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/dma.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/dma.c deleted file mode 100644 index 5cc9aa81..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/dma.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/*************************************\ -* DMA and interrupt masking functions * -\*************************************/ - -/** - * DOC: DMA and interrupt masking functions - * - * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and - * handle queue setup for 5210 chipset (rest are handled on qcu.c). - * Also we setup interrupt mask register (IMR) and read the various interrupt - * status registers (ISR). - */ - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - - -/*********\ -* Receive * -\*********/ - -/** - * ath5k_hw_start_rx_dma() - Start DMA receive - * @ah: The &struct ath5k_hw - */ -void -ath5k_hw_start_rx_dma(struct ath5k_hw *ah) -{ - ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); - ath5k_hw_reg_read(ah, AR5K_CR); -} - -/** - * ath5k_hw_stop_rx_dma() - Stop DMA receive - * @ah: The &struct ath5k_hw - */ -static int -ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) -{ - unsigned int i; - - ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); - - /* - * It may take some time to disable the DMA receive unit - */ - for (i = 1000; i > 0 && - (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; - i--) - udelay(100); - - if (!i) - ATH5K_DBG(ah, ATH5K_DEBUG_DMA, - "failed to stop RX DMA !\n"); - - return i ? 0 : -EBUSY; -} - -/** - * ath5k_hw_get_rxdp() - Get RX Descriptor's address - * @ah: The &struct ath5k_hw - */ -u32 -ath5k_hw_get_rxdp(struct ath5k_hw *ah) -{ - return ath5k_hw_reg_read(ah, AR5K_RXDP); -} - -/** - * ath5k_hw_set_rxdp() - Set RX Descriptor's address - * @ah: The &struct ath5k_hw - * @phys_addr: RX descriptor address - * - * Returns -EIO if rx is active - */ -int -ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) -{ - if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) { - ATH5K_DBG(ah, ATH5K_DEBUG_DMA, - "tried to set RXDP while rx was active !\n"); - return -EIO; - } - - ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); - return 0; -} - - -/**********\ -* Transmit * -\**********/ - -/** - * ath5k_hw_start_tx_dma() - Start DMA transmit for a specific queue - * @ah: The &struct ath5k_hw - * @queue: The hw queue number - * - * Start DMA transmit for a specific queue and since 5210 doesn't have - * QCU/DCU, set up queue parameters for 5210 here based on queue type (one - * queue for normal data and one queue for beacons). For queue setup - * on newer chips check out qcu.c. Returns -EINVAL if queue number is out - * of range or if queue is already disabled. - * - * NOTE: Must be called after setting up tx control descriptor for that - * queue (see below). - */ -int -ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) -{ - u32 tx_queue; - - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - /* Return if queue is declared inactive */ - if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return -EINVAL; - - if (ah->ah_version == AR5K_AR5210) { - tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); - - /* - * Set the queue by type on 5210 - */ - switch (ah->ah_txq[queue].tqi_type) { - case AR5K_TX_QUEUE_DATA: - tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0; - break; - case AR5K_TX_QUEUE_BEACON: - tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1; - ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, - AR5K_BSR); - break; - case AR5K_TX_QUEUE_CAB: - tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1; - ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V | - AR5K_BCR_BDMAE, AR5K_BSR); - break; - default: - return -EINVAL; - } - /* Start queue */ - ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); - ath5k_hw_reg_read(ah, AR5K_CR); - } else { - /* Return if queue is disabled */ - if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue)) - return -EIO; - - /* Start queue */ - AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue); - } - - return 0; -} - -/** - * ath5k_hw_stop_tx_dma() - Stop DMA transmit on a specific queue - * @ah: The &struct ath5k_hw - * @queue: The hw queue number - * - * Stop DMA transmit on a specific hw queue and drain queue so we don't - * have any pending frames. Returns -EBUSY if we still have pending frames, - * -EINVAL if queue number is out of range or inactive. - */ -static int -ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) -{ - unsigned int i = 40; - u32 tx_queue, pending; - - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - /* Return if queue is declared inactive */ - if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return -EINVAL; - - if (ah->ah_version == AR5K_AR5210) { - tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); - - /* - * Set by queue type - */ - switch (ah->ah_txq[queue].tqi_type) { - case AR5K_TX_QUEUE_DATA: - tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0; - break; - case AR5K_TX_QUEUE_BEACON: - case AR5K_TX_QUEUE_CAB: - /* XXX Fix me... */ - tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1; - ath5k_hw_reg_write(ah, 0, AR5K_BSR); - break; - default: - return -EINVAL; - } - - /* Stop queue */ - ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); - ath5k_hw_reg_read(ah, AR5K_CR); - } else { - - /* - * Enable DCU early termination to quickly - * flush any pending frames from QCU - */ - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_DCU_EARLY); - - /* - * Schedule TX disable and wait until queue is empty - */ - AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); - - /* Wait for queue to stop */ - for (i = 1000; i > 0 && - (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0); - i--) - udelay(100); - - if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) - ATH5K_DBG(ah, ATH5K_DEBUG_DMA, - "queue %i didn't stop !\n", queue); - - /* Check for pending frames */ - i = 1000; - do { - pending = ath5k_hw_reg_read(ah, - AR5K_QUEUE_STATUS(queue)) & - AR5K_QCU_STS_FRMPENDCNT; - udelay(100); - } while (--i && pending); - - /* For 2413+ order PCU to drop packets using - * QUIET mechanism */ - if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) && - pending) { - /* Set periodicity and duration */ - ath5k_hw_reg_write(ah, - AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)| - AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR), - AR5K_QUIET_CTL2); - - /* Enable quiet period for current TSF */ - ath5k_hw_reg_write(ah, - AR5K_QUIET_CTL1_QT_EN | - AR5K_REG_SM(ath5k_hw_reg_read(ah, - AR5K_TSF_L32_5211) >> 10, - AR5K_QUIET_CTL1_NEXT_QT_TSF), - AR5K_QUIET_CTL1); - - /* Force channel idle high */ - AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); - - /* Wait a while and disable mechanism */ - udelay(400); - AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, - AR5K_QUIET_CTL1_QT_EN); - - /* Re-check for pending frames */ - i = 100; - do { - pending = ath5k_hw_reg_read(ah, - AR5K_QUEUE_STATUS(queue)) & - AR5K_QCU_STS_FRMPENDCNT; - udelay(100); - } while (--i && pending); - - AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); - - if (pending) - ATH5K_DBG(ah, ATH5K_DEBUG_DMA, - "quiet mechanism didn't work q:%i !\n", - queue); - } - - /* - * Disable DCU early termination - */ - AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_DCU_EARLY); - - /* Clear register */ - ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); - if (pending) { - ATH5K_DBG(ah, ATH5K_DEBUG_DMA, - "tx dma didn't stop (q:%i, frm:%i) !\n", - queue, pending); - return -EBUSY; - } - } - - /* TODO: Check for success on 5210 else return error */ - return 0; -} - -/** - * ath5k_hw_stop_beacon_queue() - Stop beacon queue - * @ah: The &struct ath5k_hw - * @queue: The queue number - * - * Returns -EIO if queue didn't stop - */ -int -ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue) -{ - int ret; - ret = ath5k_hw_stop_tx_dma(ah, queue); - if (ret) { - ATH5K_DBG(ah, ATH5K_DEBUG_DMA, - "beacon queue didn't stop !\n"); - return -EIO; - } - return 0; -} - -/** - * ath5k_hw_get_txdp() - Get TX Descriptor's address for a specific queue - * @ah: The &struct ath5k_hw - * @queue: The hw queue number - * - * Get TX descriptor's address for a specific queue. For 5210 we ignore - * the queue number and use tx queue type since we only have 2 queues. - * We use TXDP0 for normal data queue and TXDP1 for beacon queue. - * For newer chips with QCU/DCU we just read the corresponding TXDP register. - * - * XXX: Is TXDP read and clear ? - */ -u32 -ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue) -{ - u16 tx_reg; - - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - /* - * Get the transmit queue descriptor pointer from the selected queue - */ - /*5210 doesn't have QCU*/ - if (ah->ah_version == AR5K_AR5210) { - switch (ah->ah_txq[queue].tqi_type) { - case AR5K_TX_QUEUE_DATA: - tx_reg = AR5K_NOQCU_TXDP0; - break; - case AR5K_TX_QUEUE_BEACON: - case AR5K_TX_QUEUE_CAB: - tx_reg = AR5K_NOQCU_TXDP1; - break; - default: - return 0xffffffff; - } - } else { - tx_reg = AR5K_QUEUE_TXDP(queue); - } - - return ath5k_hw_reg_read(ah, tx_reg); -} - -/** - * ath5k_hw_set_txdp() - Set TX Descriptor's address for a specific queue - * @ah: The &struct ath5k_hw - * @queue: The hw queue number - * @phys_addr: The physical address - * - * Set TX descriptor's address for a specific queue. For 5210 we ignore - * the queue number and we use tx queue type since we only have 2 queues - * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue. - * For newer chips with QCU/DCU we just set the corresponding TXDP register. - * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still - * active. - */ -int -ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) -{ - u16 tx_reg; - - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - /* - * Set the transmit queue descriptor pointer register by type - * on 5210 - */ - if (ah->ah_version == AR5K_AR5210) { - switch (ah->ah_txq[queue].tqi_type) { - case AR5K_TX_QUEUE_DATA: - tx_reg = AR5K_NOQCU_TXDP0; - break; - case AR5K_TX_QUEUE_BEACON: - case AR5K_TX_QUEUE_CAB: - tx_reg = AR5K_NOQCU_TXDP1; - break; - default: - return -EINVAL; - } - } else { - /* - * Set the transmit queue descriptor pointer for - * the selected queue on QCU for 5211+ - * (this won't work if the queue is still active) - */ - if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) - return -EIO; - - tx_reg = AR5K_QUEUE_TXDP(queue); - } - - /* Set descriptor pointer */ - ath5k_hw_reg_write(ah, phys_addr, tx_reg); - - return 0; -} - -/** - * ath5k_hw_update_tx_triglevel() - Update tx trigger level - * @ah: The &struct ath5k_hw - * @increase: Flag to force increase of trigger level - * - * This function increases/decreases the tx trigger level for the tx fifo - * buffer (aka FIFO threshold) that is used to indicate when PCU flushes - * the buffer and transmits its data. Lowering this results sending small - * frames more quickly but can lead to tx underruns, raising it a lot can - * result other problems. Right now we start with the lowest possible - * (64Bytes) and if we get tx underrun we increase it using the increase - * flag. Returns -EIO if we have reached maximum/minimum. - * - * XXX: Link this with tx DMA size ? - * XXX2: Use it to save interrupts ? - */ -int -ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) -{ - u32 trigger_level, imr; - int ret = -EIO; - - /* - * Disable interrupts by setting the mask - */ - imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL); - - trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG), - AR5K_TXCFG_TXFULL); - - if (!increase) { - if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES) - goto done; - } else - trigger_level += - ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2); - - /* - * Update trigger level on success - */ - if (ah->ah_version == AR5K_AR5210) - ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL); - else - AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_TXFULL, trigger_level); - - ret = 0; - -done: - /* - * Restore interrupt mask - */ - ath5k_hw_set_imr(ah, imr); - - return ret; -} - - -/*******************\ -* Interrupt masking * -\*******************/ - -/** - * ath5k_hw_is_intr_pending() - Check if we have pending interrupts - * @ah: The &struct ath5k_hw - * - * Check if we have pending interrupts to process. Returns 1 if we - * have pending interrupts and 0 if we haven't. - */ -bool -ath5k_hw_is_intr_pending(struct ath5k_hw *ah) -{ - return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; -} - -/** - * ath5k_hw_get_isr() - Get interrupt status - * @ah: The @struct ath5k_hw - * @interrupt_mask: Driver's interrupt mask used to filter out - * interrupts in sw. - * - * This function is used inside our interrupt handler to determine the reason - * for the interrupt by reading Primary Interrupt Status Register. Returns an - * abstract interrupt status mask which is mostly ISR with some uncommon bits - * being mapped on some standard non hw-specific positions - * (check out &ath5k_int). - * - * NOTE: We do write-to-clear, so the active PISR/SISR bits at the time this - * function gets called are cleared on return. - */ -int -ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) -{ - u32 data = 0; - - /* - * Read interrupt status from Primary Interrupt - * Register. - * - * Note: PISR/SISR Not available on 5210 - */ - if (ah->ah_version == AR5K_AR5210) { - u32 isr = 0; - isr = ath5k_hw_reg_read(ah, AR5K_ISR); - if (unlikely(isr == AR5K_INT_NOCARD)) { - *interrupt_mask = isr; - return -ENODEV; - } - - /* - * Filter out the non-common bits from the interrupt - * status. - */ - *interrupt_mask = (isr & AR5K_INT_COMMON) & ah->ah_imr; - - /* Hanlde INT_FATAL */ - if (unlikely(isr & (AR5K_ISR_SSERR | AR5K_ISR_MCABT - | AR5K_ISR_DPERR))) - *interrupt_mask |= AR5K_INT_FATAL; - - /* - * XXX: BMISS interrupts may occur after association. - * I found this on 5210 code but it needs testing. If this is - * true we should disable them before assoc and re-enable them - * after a successful assoc + some jiffies. - interrupt_mask &= ~AR5K_INT_BMISS; - */ - - data = isr; - } else { - u32 pisr = 0; - u32 pisr_clear = 0; - u32 sisr0 = 0; - u32 sisr1 = 0; - u32 sisr2 = 0; - u32 sisr3 = 0; - u32 sisr4 = 0; - - /* Read PISR and SISRs... */ - pisr = ath5k_hw_reg_read(ah, AR5K_PISR); - if (unlikely(pisr == AR5K_INT_NOCARD)) { - *interrupt_mask = pisr; - return -ENODEV; - } - - sisr0 = ath5k_hw_reg_read(ah, AR5K_SISR0); - sisr1 = ath5k_hw_reg_read(ah, AR5K_SISR1); - sisr2 = ath5k_hw_reg_read(ah, AR5K_SISR2); - sisr3 = ath5k_hw_reg_read(ah, AR5K_SISR3); - sisr4 = ath5k_hw_reg_read(ah, AR5K_SISR4); - - /* - * PISR holds the logical OR of interrupt bits - * from SISR registers: - * - * TXOK and TXDESC -> Logical OR of TXOK and TXDESC - * per-queue bits on SISR0 - * - * TXERR and TXEOL -> Logical OR of TXERR and TXEOL - * per-queue bits on SISR1 - * - * TXURN -> Logical OR of TXURN per-queue bits on SISR2 - * - * HIUERR -> Logical OR of MCABT, SSERR and DPER bits on SISR2 - * - * BCNMISC -> Logical OR of TIM, CAB_END, DTIM_SYNC - * BCN_TIMEOUT, CAB_TIMEOUT and DTIM - * (and TSFOOR ?) bits on SISR2 - * - * QCBRORN and QCBRURN -> Logical OR of QCBRORN and - * QCBRURN per-queue bits on SISR3 - * QTRIG -> Logical OR of QTRIG per-queue bits on SISR4 - * - * If we clean these bits on PISR we 'll also clear all - * related bits from SISRs, e.g. if we write the TXOK bit on - * PISR we 'll clean all TXOK bits from SISR0 so if a new TXOK - * interrupt got fired for another queue while we were reading - * the interrupt registers and we write back the TXOK bit on - * PISR we 'll lose it. So make sure that we don't write back - * on PISR any bits that come from SISRs. Clearing them from - * SISRs will also clear PISR so no need to worry here. - */ - - pisr_clear = pisr & ~AR5K_ISR_BITS_FROM_SISRS; - - /* - * Write to clear them... - * Note: This means that each bit we write back - * to the registers will get cleared, leaving the - * rest unaffected. So this won't affect new interrupts - * we didn't catch while reading/processing, we 'll get - * them next time get_isr gets called. - */ - ath5k_hw_reg_write(ah, sisr0, AR5K_SISR0); - ath5k_hw_reg_write(ah, sisr1, AR5K_SISR1); - ath5k_hw_reg_write(ah, sisr2, AR5K_SISR2); - ath5k_hw_reg_write(ah, sisr3, AR5K_SISR3); - ath5k_hw_reg_write(ah, sisr4, AR5K_SISR4); - ath5k_hw_reg_write(ah, pisr_clear, AR5K_PISR); - /* Flush previous write */ - ath5k_hw_reg_read(ah, AR5K_PISR); - - /* - * Filter out the non-common bits from the interrupt - * status. - */ - *interrupt_mask = (pisr & AR5K_INT_COMMON) & ah->ah_imr; - - - /* We treat TXOK,TXDESC, TXERR and TXEOL - * the same way (schedule the tx tasklet) - * so we track them all together per queue */ - if (pisr & AR5K_ISR_TXOK) - ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr0, - AR5K_SISR0_QCU_TXOK); - - if (pisr & AR5K_ISR_TXDESC) - ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr0, - AR5K_SISR0_QCU_TXDESC); - - if (pisr & AR5K_ISR_TXERR) - ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr1, - AR5K_SISR1_QCU_TXERR); - - if (pisr & AR5K_ISR_TXEOL) - ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr1, - AR5K_SISR1_QCU_TXEOL); - - /* Currently this is not much usefull since we treat - * all queues the same way if we get a TXURN (update - * tx trigger level) but we might need it later on*/ - if (pisr & AR5K_ISR_TXURN) - ah->ah_txq_isr_txurn |= AR5K_REG_MS(sisr2, - AR5K_SISR2_QCU_TXURN); - - /* Misc Beacon related interrupts */ - - /* For AR5211 */ - if (pisr & AR5K_ISR_TIM) - *interrupt_mask |= AR5K_INT_TIM; - - /* For AR5212+ */ - if (pisr & AR5K_ISR_BCNMISC) { - if (sisr2 & AR5K_SISR2_TIM) - *interrupt_mask |= AR5K_INT_TIM; - if (sisr2 & AR5K_SISR2_DTIM) - *interrupt_mask |= AR5K_INT_DTIM; - if (sisr2 & AR5K_SISR2_DTIM_SYNC) - *interrupt_mask |= AR5K_INT_DTIM_SYNC; - if (sisr2 & AR5K_SISR2_BCN_TIMEOUT) - *interrupt_mask |= AR5K_INT_BCN_TIMEOUT; - if (sisr2 & AR5K_SISR2_CAB_TIMEOUT) - *interrupt_mask |= AR5K_INT_CAB_TIMEOUT; - } - - /* Below interrupts are unlikely to happen */ - - /* HIU = Host Interface Unit (PCI etc) - * Can be one of MCABT, SSERR, DPERR from SISR2 */ - if (unlikely(pisr & (AR5K_ISR_HIUERR))) - *interrupt_mask |= AR5K_INT_FATAL; - - /*Beacon Not Ready*/ - if (unlikely(pisr & (AR5K_ISR_BNR))) - *interrupt_mask |= AR5K_INT_BNR; - - /* A queue got CBR overrun */ - if (unlikely(pisr & (AR5K_ISR_QCBRORN))) { - *interrupt_mask |= AR5K_INT_QCBRORN; - ah->ah_txq_isr_qcborn |= AR5K_REG_MS(sisr3, - AR5K_SISR3_QCBRORN); - } - - /* A queue got CBR underrun */ - if (unlikely(pisr & (AR5K_ISR_QCBRURN))) { - *interrupt_mask |= AR5K_INT_QCBRURN; - ah->ah_txq_isr_qcburn |= AR5K_REG_MS(sisr3, - AR5K_SISR3_QCBRURN); - } - - /* A queue got triggered */ - if (unlikely(pisr & (AR5K_ISR_QTRIG))) { - *interrupt_mask |= AR5K_INT_QTRIG; - ah->ah_txq_isr_qtrig |= AR5K_REG_MS(sisr4, - AR5K_SISR4_QTRIG); - } - - data = pisr; - } - - /* - * In case we didn't handle anything, - * print the register value. - */ - if (unlikely(*interrupt_mask == 0 && net_ratelimit())) - ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr); - - return 0; -} - -/** - * ath5k_hw_set_imr() - Set interrupt mask - * @ah: The &struct ath5k_hw - * @new_mask: The new interrupt mask to be set - * - * Set the interrupt mask in hw to save interrupts. We do that by mapping - * ath5k_int bits to hw-specific bits to remove abstraction and writing - * Interrupt Mask Register. - */ -enum ath5k_int -ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask) -{ - enum ath5k_int old_mask, int_mask; - - old_mask = ah->ah_imr; - - /* - * Disable card interrupts to prevent any race conditions - * (they will be re-enabled afterwards if AR5K_INT GLOBAL - * is set again on the new mask). - */ - if (old_mask & AR5K_INT_GLOBAL) { - ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER); - ath5k_hw_reg_read(ah, AR5K_IER); - } - - /* - * Add additional, chipset-dependent interrupt mask flags - * and write them to the IMR (interrupt mask register). - */ - int_mask = new_mask & AR5K_INT_COMMON; - - if (ah->ah_version != AR5K_AR5210) { - /* Preserve per queue TXURN interrupt mask */ - u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2) - & AR5K_SIMR2_QCU_TXURN; - - /* Fatal interrupt abstraction for 5211+ */ - if (new_mask & AR5K_INT_FATAL) { - int_mask |= AR5K_IMR_HIUERR; - simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR - | AR5K_SIMR2_DPERR); - } - - /* Misc beacon related interrupts */ - if (new_mask & AR5K_INT_TIM) - int_mask |= AR5K_IMR_TIM; - - if (new_mask & AR5K_INT_TIM) - simr2 |= AR5K_SISR2_TIM; - if (new_mask & AR5K_INT_DTIM) - simr2 |= AR5K_SISR2_DTIM; - if (new_mask & AR5K_INT_DTIM_SYNC) - simr2 |= AR5K_SISR2_DTIM_SYNC; - if (new_mask & AR5K_INT_BCN_TIMEOUT) - simr2 |= AR5K_SISR2_BCN_TIMEOUT; - if (new_mask & AR5K_INT_CAB_TIMEOUT) - simr2 |= AR5K_SISR2_CAB_TIMEOUT; - - /*Beacon Not Ready*/ - if (new_mask & AR5K_INT_BNR) - int_mask |= AR5K_INT_BNR; - - /* Note: Per queue interrupt masks - * are set via ath5k_hw_reset_tx_queue() (qcu.c) */ - ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR); - ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2); - - } else { - /* Fatal interrupt abstraction for 5210 */ - if (new_mask & AR5K_INT_FATAL) - int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT - | AR5K_IMR_HIUERR | AR5K_IMR_DPERR); - - /* Only common interrupts left for 5210 (no SIMRs) */ - ath5k_hw_reg_write(ah, int_mask, AR5K_IMR); - } - - /* If RXNOFRM interrupt is masked disable it - * by setting AR5K_RXNOFRM to zero */ - if (!(new_mask & AR5K_INT_RXNOFRM)) - ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM); - - /* Store new interrupt mask */ - ah->ah_imr = new_mask; - - /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */ - if (new_mask & AR5K_INT_GLOBAL) { - ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER); - ath5k_hw_reg_read(ah, AR5K_IER); - } - - return old_mask; -} - - -/********************\ - Init/Stop functions -\********************/ - -/** - * ath5k_hw_dma_init() - Initialize DMA unit - * @ah: The &struct ath5k_hw - * - * Set DMA size and pre-enable interrupts - * (driver handles tx/rx buffer setup and - * dma start/stop) - * - * XXX: Save/restore RXDP/TXDP registers ? - */ -void -ath5k_hw_dma_init(struct ath5k_hw *ah) -{ - /* - * Set Rx/Tx DMA Configuration - * - * Set standard DMA size (128). Note that - * a DMA size of 512 causes rx overruns and tx errors - * on pci-e cards (tested on 5424 but since rx overruns - * also occur on 5416/5418 with madwifi we set 128 - * for all PCI-E cards to be safe). - * - * XXX: need to check 5210 for this - * TODO: Check out tx trigger level, it's always 64 on dumps but I - * guess we can tweak it and see how it goes ;-) - */ - if (ah->ah_version != AR5K_AR5210) { - AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); - AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, - AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); - } - - /* Pre-enable interrupts on 5211/5212*/ - if (ah->ah_version != AR5K_AR5210) - ath5k_hw_set_imr(ah, ah->ah_imr); - -} - -/** - * ath5k_hw_dma_stop() - stop DMA unit - * @ah: The &struct ath5k_hw - * - * Stop tx/rx DMA and interrupts. Returns - * -EBUSY if tx or rx dma failed to stop. - * - * XXX: Sometimes DMA unit hangs and we have - * stuck frames on tx queues, only a reset - * can fix that. - */ -int -ath5k_hw_dma_stop(struct ath5k_hw *ah) -{ - int i, qmax, err; - err = 0; - - /* Disable interrupts */ - ath5k_hw_set_imr(ah, 0); - - /* Stop rx dma */ - err = ath5k_hw_stop_rx_dma(ah); - if (err) - return err; - - /* Clear any pending interrupts - * and disable tx dma */ - if (ah->ah_version != AR5K_AR5210) { - ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); - qmax = AR5K_NUM_TX_QUEUES; - } else { - /* PISR/SISR Not available on 5210 */ - ath5k_hw_reg_read(ah, AR5K_ISR); - qmax = AR5K_NUM_TX_QUEUES_NOQCU; - } - - for (i = 0; i < qmax; i++) { - err = ath5k_hw_stop_tx_dma(ah, i); - /* -EINVAL -> queue inactive */ - if (err && err != -EINVAL) - return err; - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/eeprom.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/eeprom.c deleted file mode 100644 index cd708c15..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/eeprom.c +++ /dev/null @@ -1,1792 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org> - * - * Permission to use, copy, modify, and 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. - * - */ - -/*************************************\ -* EEPROM access functions and helpers * -\*************************************/ - -#include <linux/slab.h> - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - - -/******************\ -* Helper functions * -\******************/ - -/* - * Translate binary channel representation in EEPROM to frequency - */ -static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, - unsigned int mode) -{ - u16 val; - - if (bin == AR5K_EEPROM_CHANNEL_DIS) - return bin; - - if (mode == AR5K_EEPROM_MODE_11A) { - if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) - val = (5 * bin) + 4800; - else - val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : - (bin * 10) + 5100; - } else { - if (ee->ee_version > AR5K_EEPROM_VERSION_3_2) - val = bin + 2300; - else - val = bin + 2400; - } - - return val; -} - - -/*********\ -* Parsers * -\*********/ - -/* - * Initialize eeprom & capabilities structs - */ -static int -ath5k_eeprom_init_header(struct ath5k_hw *ah) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u16 val; - u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; - - /* - * Read values from EEPROM and store them in the capability structure - */ - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header); - - /* Return if we have an old EEPROM */ - if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) - return 0; - - /* - * Validate the checksum of the EEPROM date. There are some - * devices with invalid EEPROMs. - */ - AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val); - if (val) { - eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) << - AR5K_EEPROM_SIZE_ENDLOC_SHIFT; - AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val); - eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE; - - /* - * Fail safe check to prevent stupid loops due - * to busted EEPROMs. XXX: This value is likely too - * big still, waiting on a better value. - */ - if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { - ATH5K_ERR(ah, "Invalid max custom EEPROM size: " - "%d (0x%04x) max expected: %d (0x%04x)\n", - eep_max, eep_max, - 3 * AR5K_EEPROM_INFO_MAX, - 3 * AR5K_EEPROM_INFO_MAX); - return -EIO; - } - } - - for (cksum = 0, offset = 0; offset < eep_max; offset++) { - AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); - cksum ^= val; - } - if (cksum != AR5K_EEPROM_INFO_CKSUM) { - ATH5K_ERR(ah, "Invalid EEPROM " - "checksum: 0x%04x eep_max: 0x%04x (%s)\n", - cksum, eep_max, - eep_max == AR5K_EEPROM_INFO_MAX ? - "default size" : "custom size"); - return -EIO; - } - - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), - ee_ant_gain); - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); - - /* XXX: Don't know which versions include these two */ - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2); - - if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3); - - if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) { - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5); - AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6); - } - } - - if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { - AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); - ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; - ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; - - AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); - ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; - ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; - } - - AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val); - - if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val) - ee->ee_is_hb63 = true; - else - ee->ee_is_hb63 = false; - - AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val); - ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL); - ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false; - - /* Check if PCIE_OFFSET points to PCIE_SERDES_SECTION - * and enable serdes programming if needed. - * - * XXX: Serdes values seem to be fixed so - * no need to read them here, we write them - * during ath5k_hw_init */ - AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); - ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? - true : false; - - return 0; -} - - -/* - * Read antenna infos from eeprom - */ -static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, - unsigned int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 o = *offset; - u16 val; - int i = 0; - - AR5K_EEPROM_READ(o++, val); - ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; - ee->ee_atn_tx_rx[mode] = (val >> 2) & 0x3f; - ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; - ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; - ee->ee_ant_control[mode][i++] = val & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; - ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; - ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; - ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; - ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; - ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; - ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; - ee->ee_ant_control[mode][i++] = val & 0x3f; - - /* Get antenna switch tables */ - ah->ah_ant_ctl[mode][AR5K_ANT_CTL] = - (ee->ee_ant_control[mode][0] << 4); - ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] = - ee->ee_ant_control[mode][1] | - (ee->ee_ant_control[mode][2] << 6) | - (ee->ee_ant_control[mode][3] << 12) | - (ee->ee_ant_control[mode][4] << 18) | - (ee->ee_ant_control[mode][5] << 24); - ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] = - ee->ee_ant_control[mode][6] | - (ee->ee_ant_control[mode][7] << 6) | - (ee->ee_ant_control[mode][8] << 12) | - (ee->ee_ant_control[mode][9] << 18) | - (ee->ee_ant_control[mode][10] << 24); - - /* return new offset */ - *offset = o; - - return 0; -} - -/* - * Read supported modes and some mode-specific calibration data - * from eeprom - */ -static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, - unsigned int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 o = *offset; - u16 val; - - ee->ee_n_piers[mode] = 0; - AR5K_EEPROM_READ(o++, val); - ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); - switch (mode) { - case AR5K_EEPROM_MODE_11A: - ee->ee_ob[mode][3] = (val >> 5) & 0x7; - ee->ee_db[mode][3] = (val >> 2) & 0x7; - ee->ee_ob[mode][2] = (val << 1) & 0x7; - - AR5K_EEPROM_READ(o++, val); - ee->ee_ob[mode][2] |= (val >> 15) & 0x1; - ee->ee_db[mode][2] = (val >> 12) & 0x7; - ee->ee_ob[mode][1] = (val >> 9) & 0x7; - ee->ee_db[mode][1] = (val >> 6) & 0x7; - ee->ee_ob[mode][0] = (val >> 3) & 0x7; - ee->ee_db[mode][0] = val & 0x7; - break; - case AR5K_EEPROM_MODE_11G: - case AR5K_EEPROM_MODE_11B: - ee->ee_ob[mode][1] = (val >> 4) & 0x7; - ee->ee_db[mode][1] = val & 0x7; - break; - } - - AR5K_EEPROM_READ(o++, val); - ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; - ee->ee_thr_62[mode] = val & 0xff; - - if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) - ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28; - - AR5K_EEPROM_READ(o++, val); - ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; - ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; - - AR5K_EEPROM_READ(o++, val); - ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; - - if ((val & 0xff) & 0x80) - ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); - else - ee->ee_noise_floor_thr[mode] = val & 0xff; - - if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) - ee->ee_noise_floor_thr[mode] = - mode == AR5K_EEPROM_MODE_11A ? -54 : -1; - - AR5K_EEPROM_READ(o++, val); - ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; - ee->ee_x_gain[mode] = (val >> 1) & 0xf; - ee->ee_xpd[mode] = val & 0x1; - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && - mode != AR5K_EEPROM_MODE_11B) - ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { - AR5K_EEPROM_READ(o++, val); - ee->ee_false_detect[mode] = (val >> 6) & 0x7f; - - if (mode == AR5K_EEPROM_MODE_11A) - ee->ee_xr_power[mode] = val & 0x3f; - else { - /* b_DB_11[bg] and b_OB_11[bg] */ - ee->ee_ob[mode][0] = val & 0x7; - ee->ee_db[mode][0] = (val >> 3) & 0x7; - } - } - - if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) { - ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; - ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; - } else { - ee->ee_i_gain[mode] = (val >> 13) & 0x7; - - AR5K_EEPROM_READ(o++, val); - ee->ee_i_gain[mode] |= (val << 3) & 0x38; - - if (mode == AR5K_EEPROM_MODE_11G) { - ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6) - ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; - } - } - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && - mode == AR5K_EEPROM_MODE_11A) { - ee->ee_i_cal[mode] = (val >> 8) & 0x3f; - ee->ee_q_cal[mode] = (val >> 3) & 0x1f; - } - - if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0) - goto done; - - /* Note: >= v5 have bg freq piers on another location - * so these freq piers are ignored for >= v5 (should be 0xff - * anyway) */ - switch (mode) { - case AR5K_EEPROM_MODE_11A: - if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1) - break; - - AR5K_EEPROM_READ(o++, val); - ee->ee_margin_tx_rx[mode] = val & 0x3f; - break; - case AR5K_EEPROM_MODE_11B: - AR5K_EEPROM_READ(o++, val); - - ee->ee_pwr_cal_b[0].freq = - ath5k_eeprom_bin2freq(ee, val & 0xff, mode); - if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS) - ee->ee_n_piers[mode]++; - - ee->ee_pwr_cal_b[1].freq = - ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); - if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS) - ee->ee_n_piers[mode]++; - - AR5K_EEPROM_READ(o++, val); - ee->ee_pwr_cal_b[2].freq = - ath5k_eeprom_bin2freq(ee, val & 0xff, mode); - if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS) - ee->ee_n_piers[mode]++; - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) - ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; - break; - case AR5K_EEPROM_MODE_11G: - AR5K_EEPROM_READ(o++, val); - - ee->ee_pwr_cal_g[0].freq = - ath5k_eeprom_bin2freq(ee, val & 0xff, mode); - if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS) - ee->ee_n_piers[mode]++; - - ee->ee_pwr_cal_g[1].freq = - ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); - if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS) - ee->ee_n_piers[mode]++; - - AR5K_EEPROM_READ(o++, val); - ee->ee_turbo_max_power[mode] = val & 0x7f; - ee->ee_xr_power[mode] = (val >> 7) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_pwr_cal_g[2].freq = - ath5k_eeprom_bin2freq(ee, val & 0xff, mode); - if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS) - ee->ee_n_piers[mode]++; - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) - ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; - - AR5K_EEPROM_READ(o++, val); - ee->ee_i_cal[mode] = (val >> 5) & 0x3f; - ee->ee_q_cal[mode] = val & 0x1f; - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { - AR5K_EEPROM_READ(o++, val); - ee->ee_cck_ofdm_gain_delta = val & 0xff; - } - break; - } - - /* - * Read turbo mode information on newer EEPROM versions - */ - if (ee->ee_version < AR5K_EEPROM_VERSION_5_0) - goto done; - - switch (mode) { - case AR5K_EEPROM_MODE_11A: - ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f; - - ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7; - AR5K_EEPROM_READ(o++, val); - ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3; - ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f; - - ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f; - AR5K_EEPROM_READ(o++, val); - ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7; - ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff; - - if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2) - ee->ee_pd_gain_overlap = (val >> 9) & 0xf; - break; - case AR5K_EEPROM_MODE_11G: - ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f; - - ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7; - AR5K_EEPROM_READ(o++, val); - ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1; - ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f; - - ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f; - AR5K_EEPROM_READ(o++, val); - ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5; - ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff; - break; - } - -done: - /* return new offset */ - *offset = o; - - return 0; -} - -/* Read mode-specific data (except power calibration data) */ -static int -ath5k_eeprom_init_modes(struct ath5k_hw *ah) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 mode_offset[3]; - unsigned int mode; - u32 offset; - int ret; - - /* - * Get values for all modes - */ - mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); - mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); - mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); - - ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] = - AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); - - for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) { - offset = mode_offset[mode]; - - ret = ath5k_eeprom_read_ants(ah, &offset, mode); - if (ret) - return ret; - - ret = ath5k_eeprom_read_modes(ah, &offset, mode); - if (ret) - return ret; - } - - /* override for older eeprom versions for better performance */ - if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) { - ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15; - ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28; - ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28; - } - - return 0; -} - -/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff - * frequency mask) */ -static inline int -ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, - struct ath5k_chan_pcal_info *pc, unsigned int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - int o = *offset; - int i = 0; - u8 freq1, freq2; - u16 val; - - ee->ee_n_piers[mode] = 0; - while (i < max) { - AR5K_EEPROM_READ(o++, val); - - freq1 = val & 0xff; - if (!freq1) - break; - - pc[i++].freq = ath5k_eeprom_bin2freq(ee, - freq1, mode); - ee->ee_n_piers[mode]++; - - freq2 = (val >> 8) & 0xff; - if (!freq2) - break; - - pc[i++].freq = ath5k_eeprom_bin2freq(ee, - freq2, mode); - ee->ee_n_piers[mode]++; - } - - /* return new offset */ - *offset = o; - - return 0; -} - -/* Read frequency piers for 802.11a */ -static int -ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; - int i; - u16 val; - u8 mask; - - if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { - ath5k_eeprom_read_freq_list(ah, &offset, - AR5K_EEPROM_N_5GHZ_CHAN, pcal, - AR5K_EEPROM_MODE_11A); - } else { - mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version); - - AR5K_EEPROM_READ(offset++, val); - pcal[0].freq = (val >> 9) & mask; - pcal[1].freq = (val >> 2) & mask; - pcal[2].freq = (val << 5) & mask; - - AR5K_EEPROM_READ(offset++, val); - pcal[2].freq |= (val >> 11) & 0x1f; - pcal[3].freq = (val >> 4) & mask; - pcal[4].freq = (val << 3) & mask; - - AR5K_EEPROM_READ(offset++, val); - pcal[4].freq |= (val >> 13) & 0x7; - pcal[5].freq = (val >> 6) & mask; - pcal[6].freq = (val << 1) & mask; - - AR5K_EEPROM_READ(offset++, val); - pcal[6].freq |= (val >> 15) & 0x1; - pcal[7].freq = (val >> 8) & mask; - pcal[8].freq = (val >> 1) & mask; - pcal[9].freq = (val << 6) & mask; - - AR5K_EEPROM_READ(offset++, val); - pcal[9].freq |= (val >> 10) & 0x3f; - - /* Fixed number of piers */ - ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10; - - for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) { - pcal[i].freq = ath5k_eeprom_bin2freq(ee, - pcal[i].freq, AR5K_EEPROM_MODE_11A); - } - } - - return 0; -} - -/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */ -static inline int -ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *pcal; - - switch (mode) { - case AR5K_EEPROM_MODE_11B: - pcal = ee->ee_pwr_cal_b; - break; - case AR5K_EEPROM_MODE_11G: - pcal = ee->ee_pwr_cal_g; - break; - default: - return -EINVAL; - } - - ath5k_eeprom_read_freq_list(ah, &offset, - AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal, - mode); - - return 0; -} - - -/* - * Read power calibration for RF5111 chips - * - * For RF5111 we have an XPD -eXternal Power Detector- curve - * for each calibrated channel. Each curve has 0,5dB Power steps - * on x axis and PCDAC steps (offsets) on y axis and looks like an - * exponential function. To recreate the curve we read 11 points - * here and interpolate later. - */ - -/* Used to match PCDAC steps with power values on RF5111 chips - * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC - * steps that match with the power values we read from eeprom. On - * older eeprom versions (< 3.2) these steps are equally spaced at - * 10% of the pcdac curve -until the curve reaches its maximum- - * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) - * these 11 steps are spaced in a different way. This function returns - * the pcdac steps based on eeprom version and curve min/max so that we - * can have pcdac/pwr points. - */ -static inline void -ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) -{ - static const u16 intercepts3[] = { - 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 - }; - static const u16 intercepts3_2[] = { - 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 - }; - const u16 *ip; - int i; - - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2) - ip = intercepts3_2; - else - ip = intercepts3; - - for (i = 0; i < ARRAY_SIZE(intercepts3); i++) - vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; -} - -static int -ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *chinfo; - u8 pier, pdg; - - switch (mode) { - case AR5K_EEPROM_MODE_11A: - if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_a; - break; - case AR5K_EEPROM_MODE_11B: - if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_b; - break; - case AR5K_EEPROM_MODE_11G: - if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) - return 0; - chinfo = ee->ee_pwr_cal_g; - break; - default: - return -EINVAL; - } - - for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { - if (!chinfo[pier].pd_curves) - continue; - - for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { - struct ath5k_pdgain_info *pd = - &chinfo[pier].pd_curves[pdg]; - - kfree(pd->pd_step); - kfree(pd->pd_pwr); - } - - kfree(chinfo[pier].pd_curves); - } - - return 0; -} - -/* Convert RF5111 specific data to generic raw data - * used by interpolation code */ -static int -ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, - struct ath5k_chan_pcal_info *chinfo) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info_rf5111 *pcinfo; - struct ath5k_pdgain_info *pd; - u8 pier, point, idx; - u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; - - /* Fill raw data for each calibration pier */ - for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { - - pcinfo = &chinfo[pier].rf5111_info; - - /* Allocate pd_curves for this cal pier */ - chinfo[pier].pd_curves = - kcalloc(AR5K_EEPROM_N_PD_CURVES, - sizeof(struct ath5k_pdgain_info), - GFP_KERNEL); - - if (!chinfo[pier].pd_curves) - goto err_out; - - /* Only one curve for RF5111 - * find out which one and place - * in pd_curves. - * Note: ee_x_gain is reversed here */ - for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) { - - if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) { - pdgain_idx[0] = idx; - break; - } - } - - ee->ee_pd_gains[mode] = 1; - - pd = &chinfo[pier].pd_curves[idx]; - - pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111; - - /* Allocate pd points for this curve */ - pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, - sizeof(u8), GFP_KERNEL); - if (!pd->pd_step) - goto err_out; - - pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, - sizeof(s16), GFP_KERNEL); - if (!pd->pd_pwr) - goto err_out; - - /* Fill raw dataset - * (convert power to 0.25dB units - * for RF5112 compatibility) */ - for (point = 0; point < pd->pd_points; point++) { - - /* Absolute values */ - pd->pd_pwr[point] = 2 * pcinfo->pwr[point]; - - /* Already sorted */ - pd->pd_step[point] = pcinfo->pcdac[point]; - } - - /* Set min/max pwr */ - chinfo[pier].min_pwr = pd->pd_pwr[0]; - chinfo[pier].max_pwr = pd->pd_pwr[10]; - - } - - return 0; - -err_out: - ath5k_eeprom_free_pcal_info(ah, mode); - return -ENOMEM; -} - -/* Parse EEPROM data */ -static int -ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *pcal; - int offset, ret; - int i; - u16 val; - - offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); - switch (mode) { - case AR5K_EEPROM_MODE_11A: - if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) - return 0; - - ret = ath5k_eeprom_init_11a_pcal_freq(ah, - offset + AR5K_EEPROM_GROUP1_OFFSET); - if (ret < 0) - return ret; - - offset += AR5K_EEPROM_GROUP2_OFFSET; - pcal = ee->ee_pwr_cal_a; - break; - case AR5K_EEPROM_MODE_11B: - if (!AR5K_EEPROM_HDR_11B(ee->ee_header) && - !AR5K_EEPROM_HDR_11G(ee->ee_header)) - return 0; - - pcal = ee->ee_pwr_cal_b; - offset += AR5K_EEPROM_GROUP3_OFFSET; - - /* fixed piers */ - pcal[0].freq = 2412; - pcal[1].freq = 2447; - pcal[2].freq = 2484; - ee->ee_n_piers[mode] = 3; - break; - case AR5K_EEPROM_MODE_11G: - if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) - return 0; - - pcal = ee->ee_pwr_cal_g; - offset += AR5K_EEPROM_GROUP4_OFFSET; - - /* fixed piers */ - pcal[0].freq = 2312; - pcal[1].freq = 2412; - pcal[2].freq = 2484; - ee->ee_n_piers[mode] = 3; - break; - default: - return -EINVAL; - } - - for (i = 0; i < ee->ee_n_piers[mode]; i++) { - struct ath5k_chan_pcal_info_rf5111 *cdata = - &pcal[i].rf5111_info; - - AR5K_EEPROM_READ(offset++, val); - cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M); - cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M); - cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M); - - AR5K_EEPROM_READ(offset++, val); - cdata->pwr[0] |= ((val >> 14) & 0x3); - cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M); - cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M); - cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M); - - AR5K_EEPROM_READ(offset++, val); - cdata->pwr[3] |= ((val >> 12) & 0xf); - cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M); - cdata->pwr[5] = (val & AR5K_EEPROM_POWER_M); - - AR5K_EEPROM_READ(offset++, val); - cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M); - cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M); - cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M); - - AR5K_EEPROM_READ(offset++, val); - cdata->pwr[8] |= ((val >> 14) & 0x3); - cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M); - cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M); - - ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min, - cdata->pcdac_max, cdata->pcdac); - } - - return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal); -} - - -/* - * Read power calibration for RF5112 chips - * - * For RF5112 we have 4 XPD -eXternal Power Detector- curves - * for each calibrated channel on 0, -6, -12 and -18dBm but we only - * use the higher (3) and the lower (0) curves. Each curve has 0.5dB - * power steps on x axis and PCDAC steps on y axis and looks like a - * linear function. To recreate the curve and pass the power values - * on hw, we read 4 points for xpd 0 (lower gain -> max power) - * and 3 points for xpd 3 (higher gain -> lower power) here and - * interpolate later. - * - * Note: Many vendors just use xpd 0 so xpd 3 is zeroed. - */ - -/* Convert RF5112 specific data to generic raw data - * used by interpolation code */ -static int -ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, - struct ath5k_chan_pcal_info *chinfo) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info_rf5112 *pcinfo; - u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; - unsigned int pier, pdg, point; - - /* Fill raw data for each calibration pier */ - for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { - - pcinfo = &chinfo[pier].rf5112_info; - - /* Allocate pd_curves for this cal pier */ - chinfo[pier].pd_curves = - kcalloc(AR5K_EEPROM_N_PD_CURVES, - sizeof(struct ath5k_pdgain_info), - GFP_KERNEL); - - if (!chinfo[pier].pd_curves) - goto err_out; - - /* Fill pd_curves */ - for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { - - u8 idx = pdgain_idx[pdg]; - struct ath5k_pdgain_info *pd = - &chinfo[pier].pd_curves[idx]; - - /* Lowest gain curve (max power) */ - if (pdg == 0) { - /* One more point for better accuracy */ - pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS; - - /* Allocate pd points for this curve */ - pd->pd_step = kcalloc(pd->pd_points, - sizeof(u8), GFP_KERNEL); - - if (!pd->pd_step) - goto err_out; - - pd->pd_pwr = kcalloc(pd->pd_points, - sizeof(s16), GFP_KERNEL); - - if (!pd->pd_pwr) - goto err_out; - - /* Fill raw dataset - * (all power levels are in 0.25dB units) */ - pd->pd_step[0] = pcinfo->pcdac_x0[0]; - pd->pd_pwr[0] = pcinfo->pwr_x0[0]; - - for (point = 1; point < pd->pd_points; - point++) { - /* Absolute values */ - pd->pd_pwr[point] = - pcinfo->pwr_x0[point]; - - /* Deltas */ - pd->pd_step[point] = - pd->pd_step[point - 1] + - pcinfo->pcdac_x0[point]; - } - - /* Set min power for this frequency */ - chinfo[pier].min_pwr = pd->pd_pwr[0]; - - /* Highest gain curve (min power) */ - } else if (pdg == 1) { - - pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS; - - /* Allocate pd points for this curve */ - pd->pd_step = kcalloc(pd->pd_points, - sizeof(u8), GFP_KERNEL); - - if (!pd->pd_step) - goto err_out; - - pd->pd_pwr = kcalloc(pd->pd_points, - sizeof(s16), GFP_KERNEL); - - if (!pd->pd_pwr) - goto err_out; - - /* Fill raw dataset - * (all power levels are in 0.25dB units) */ - for (point = 0; point < pd->pd_points; - point++) { - /* Absolute values */ - pd->pd_pwr[point] = - pcinfo->pwr_x3[point]; - - /* Fixed points */ - pd->pd_step[point] = - pcinfo->pcdac_x3[point]; - } - - /* Since we have a higher gain curve - * override min power */ - chinfo[pier].min_pwr = pd->pd_pwr[0]; - } - } - } - - return 0; - -err_out: - ath5k_eeprom_free_pcal_info(ah, mode); - return -ENOMEM; -} - -/* Parse EEPROM data */ -static int -ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info; - struct ath5k_chan_pcal_info *gen_chan_info; - u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; - u32 offset; - u8 i, c; - u16 val; - u8 pd_gains = 0; - - /* Count how many curves we have and - * identify them (which one of the 4 - * available curves we have on each count). - * Curves are stored from lower (x0) to - * higher (x3) gain */ - for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) { - /* ee_x_gain[mode] is x gain mask */ - if ((ee->ee_x_gain[mode] >> i) & 0x1) - pdgain_idx[pd_gains++] = i; - } - ee->ee_pd_gains[mode] = pd_gains; - - if (pd_gains == 0 || pd_gains > 2) - return -EINVAL; - - switch (mode) { - case AR5K_EEPROM_MODE_11A: - /* - * Read 5GHz EEPROM channels - */ - offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); - ath5k_eeprom_init_11a_pcal_freq(ah, offset); - - offset += AR5K_EEPROM_GROUP2_OFFSET; - gen_chan_info = ee->ee_pwr_cal_a; - break; - case AR5K_EEPROM_MODE_11B: - offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); - if (AR5K_EEPROM_HDR_11A(ee->ee_header)) - offset += AR5K_EEPROM_GROUP3_OFFSET; - - /* NB: frequency piers parsed during mode init */ - gen_chan_info = ee->ee_pwr_cal_b; - break; - case AR5K_EEPROM_MODE_11G: - offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); - if (AR5K_EEPROM_HDR_11A(ee->ee_header)) - offset += AR5K_EEPROM_GROUP4_OFFSET; - else if (AR5K_EEPROM_HDR_11B(ee->ee_header)) - offset += AR5K_EEPROM_GROUP2_OFFSET; - - /* NB: frequency piers parsed during mode init */ - gen_chan_info = ee->ee_pwr_cal_g; - break; - default: - return -EINVAL; - } - - for (i = 0; i < ee->ee_n_piers[mode]; i++) { - chan_pcal_info = &gen_chan_info[i].rf5112_info; - - /* Power values in quarter dB - * for the lower xpd gain curve - * (0 dBm -> higher output power) */ - for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) { - AR5K_EEPROM_READ(offset++, val); - chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff); - chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff); - } - - /* PCDAC steps - * corresponding to the above power - * measurements */ - AR5K_EEPROM_READ(offset++, val); - chan_pcal_info->pcdac_x0[1] = (val & 0x1f); - chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f); - chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f); - - /* Power values in quarter dB - * for the higher xpd gain curve - * (18 dBm -> lower output power) */ - AR5K_EEPROM_READ(offset++, val); - chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff); - chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff); - - AR5K_EEPROM_READ(offset++, val); - chan_pcal_info->pwr_x3[2] = (val & 0xff); - - /* PCDAC steps - * corresponding to the above power - * measurements (fixed) */ - chan_pcal_info->pcdac_x3[0] = 20; - chan_pcal_info->pcdac_x3[1] = 35; - chan_pcal_info->pcdac_x3[2] = 63; - - if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) { - chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f); - - /* Last xpd0 power level is also channel maximum */ - gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3]; - } else { - chan_pcal_info->pcdac_x0[0] = 1; - gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff); - } - - } - - return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info); -} - - -/* - * Read power calibration for RF2413 chips - * - * For RF2413 we have a Power to PDDAC table (Power Detector) - * instead of a PCDAC and 4 pd gain curves for each calibrated channel. - * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y - * axis and looks like an exponential function like the RF5111 curve. - * - * To recreate the curves we read here the points and interpolate - * later. Note that in most cases only 2 (higher and lower) curves are - * used (like RF5112) but vendors have the opportunity to include all - * 4 curves on eeprom. The final curve (higher power) has an extra - * point for better accuracy like RF5112. - */ - -/* For RF2413 power calibration data doesn't start on a fixed location and - * if a mode is not supported, its section is missing -not zeroed-. - * So we need to calculate the starting offset for each section by using - * these two functions */ - -/* Return the size of each section based on the mode and the number of pd - * gains available (maximum 4). */ -static inline unsigned int -ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode) -{ - static const unsigned int pdgains_size[] = { 4, 6, 9, 12 }; - unsigned int sz; - - sz = pdgains_size[ee->ee_pd_gains[mode] - 1]; - sz *= ee->ee_n_piers[mode]; - - return sz; -} - -/* Return the starting offset for a section based on the modes supported - * and each section's size. */ -static unsigned int -ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode) -{ - u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); - - switch (mode) { - case AR5K_EEPROM_MODE_11G: - if (AR5K_EEPROM_HDR_11B(ee->ee_header)) - offset += ath5k_pdgains_size_2413(ee, - AR5K_EEPROM_MODE_11B) + - AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; - /* fall through */ - case AR5K_EEPROM_MODE_11B: - if (AR5K_EEPROM_HDR_11A(ee->ee_header)) - offset += ath5k_pdgains_size_2413(ee, - AR5K_EEPROM_MODE_11A) + - AR5K_EEPROM_N_5GHZ_CHAN / 2; - /* fall through */ - case AR5K_EEPROM_MODE_11A: - break; - default: - break; - } - - return offset; -} - -/* Convert RF2413 specific data to generic raw data - * used by interpolation code */ -static int -ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, - struct ath5k_chan_pcal_info *chinfo) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info_rf2413 *pcinfo; - u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; - unsigned int pier, pdg, point; - - /* Fill raw data for each calibration pier */ - for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { - - pcinfo = &chinfo[pier].rf2413_info; - - /* Allocate pd_curves for this cal pier */ - chinfo[pier].pd_curves = - kcalloc(AR5K_EEPROM_N_PD_CURVES, - sizeof(struct ath5k_pdgain_info), - GFP_KERNEL); - - if (!chinfo[pier].pd_curves) - goto err_out; - - /* Fill pd_curves */ - for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { - - u8 idx = pdgain_idx[pdg]; - struct ath5k_pdgain_info *pd = - &chinfo[pier].pd_curves[idx]; - - /* One more point for the highest power - * curve (lowest gain) */ - if (pdg == ee->ee_pd_gains[mode] - 1) - pd->pd_points = AR5K_EEPROM_N_PD_POINTS; - else - pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1; - - /* Allocate pd points for this curve */ - pd->pd_step = kcalloc(pd->pd_points, - sizeof(u8), GFP_KERNEL); - - if (!pd->pd_step) - goto err_out; - - pd->pd_pwr = kcalloc(pd->pd_points, - sizeof(s16), GFP_KERNEL); - - if (!pd->pd_pwr) - goto err_out; - - /* Fill raw dataset - * convert all pwr levels to - * quarter dB for RF5112 compatibility */ - pd->pd_step[0] = pcinfo->pddac_i[pdg]; - pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg]; - - for (point = 1; point < pd->pd_points; point++) { - - pd->pd_pwr[point] = pd->pd_pwr[point - 1] + - 2 * pcinfo->pwr[pdg][point - 1]; - - pd->pd_step[point] = pd->pd_step[point - 1] + - pcinfo->pddac[pdg][point - 1]; - - } - - /* Highest gain curve -> min power */ - if (pdg == 0) - chinfo[pier].min_pwr = pd->pd_pwr[0]; - - /* Lowest gain curve -> max power */ - if (pdg == ee->ee_pd_gains[mode] - 1) - chinfo[pier].max_pwr = - pd->pd_pwr[pd->pd_points - 1]; - } - } - - return 0; - -err_out: - ath5k_eeprom_free_pcal_info(ah, mode); - return -ENOMEM; -} - -/* Parse EEPROM data */ -static int -ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info_rf2413 *pcinfo; - struct ath5k_chan_pcal_info *chinfo; - u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; - u32 offset; - int idx, i; - u16 val; - u8 pd_gains = 0; - - /* Count how many curves we have and - * identify them (which one of the 4 - * available curves we have on each count). - * Curves are stored from higher to - * lower gain so we go backwards */ - for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) { - /* ee_x_gain[mode] is x gain mask */ - if ((ee->ee_x_gain[mode] >> idx) & 0x1) - pdgain_idx[pd_gains++] = idx; - - } - ee->ee_pd_gains[mode] = pd_gains; - - if (pd_gains == 0) - return -EINVAL; - - offset = ath5k_cal_data_offset_2413(ee, mode); - switch (mode) { - case AR5K_EEPROM_MODE_11A: - if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) - return 0; - - ath5k_eeprom_init_11a_pcal_freq(ah, offset); - offset += AR5K_EEPROM_N_5GHZ_CHAN / 2; - chinfo = ee->ee_pwr_cal_a; - break; - case AR5K_EEPROM_MODE_11B: - if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) - return 0; - - ath5k_eeprom_init_11bg_2413(ah, mode, offset); - offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; - chinfo = ee->ee_pwr_cal_b; - break; - case AR5K_EEPROM_MODE_11G: - if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) - return 0; - - ath5k_eeprom_init_11bg_2413(ah, mode, offset); - offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2; - chinfo = ee->ee_pwr_cal_g; - break; - default: - return -EINVAL; - } - - for (i = 0; i < ee->ee_n_piers[mode]; i++) { - pcinfo = &chinfo[i].rf2413_info; - - /* - * Read pwr_i, pddac_i and the first - * 2 pd points (pwr, pddac) - */ - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr_i[0] = val & 0x1f; - pcinfo->pddac_i[0] = (val >> 5) & 0x7f; - pcinfo->pwr[0][0] = (val >> 12) & 0xf; - - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac[0][0] = val & 0x3f; - pcinfo->pwr[0][1] = (val >> 6) & 0xf; - pcinfo->pddac[0][1] = (val >> 10) & 0x3f; - - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr[0][2] = val & 0xf; - pcinfo->pddac[0][2] = (val >> 4) & 0x3f; - - pcinfo->pwr[0][3] = 0; - pcinfo->pddac[0][3] = 0; - - if (pd_gains > 1) { - /* - * Pd gain 0 is not the last pd gain - * so it only has 2 pd points. - * Continue with pd gain 1. - */ - pcinfo->pwr_i[1] = (val >> 10) & 0x1f; - - pcinfo->pddac_i[1] = (val >> 15) & 0x1; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac_i[1] |= (val & 0x3F) << 1; - - pcinfo->pwr[1][0] = (val >> 6) & 0xf; - pcinfo->pddac[1][0] = (val >> 10) & 0x3f; - - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr[1][1] = val & 0xf; - pcinfo->pddac[1][1] = (val >> 4) & 0x3f; - pcinfo->pwr[1][2] = (val >> 10) & 0xf; - - pcinfo->pddac[1][2] = (val >> 14) & 0x3; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac[1][2] |= (val & 0xF) << 2; - - pcinfo->pwr[1][3] = 0; - pcinfo->pddac[1][3] = 0; - } else if (pd_gains == 1) { - /* - * Pd gain 0 is the last one so - * read the extra point. - */ - pcinfo->pwr[0][3] = (val >> 10) & 0xf; - - pcinfo->pddac[0][3] = (val >> 14) & 0x3; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac[0][3] |= (val & 0xF) << 2; - } - - /* - * Proceed with the other pd_gains - * as above. - */ - if (pd_gains > 2) { - pcinfo->pwr_i[2] = (val >> 4) & 0x1f; - pcinfo->pddac_i[2] = (val >> 9) & 0x7f; - - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr[2][0] = (val >> 0) & 0xf; - pcinfo->pddac[2][0] = (val >> 4) & 0x3f; - pcinfo->pwr[2][1] = (val >> 10) & 0xf; - - pcinfo->pddac[2][1] = (val >> 14) & 0x3; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac[2][1] |= (val & 0xF) << 2; - - pcinfo->pwr[2][2] = (val >> 4) & 0xf; - pcinfo->pddac[2][2] = (val >> 8) & 0x3f; - - pcinfo->pwr[2][3] = 0; - pcinfo->pddac[2][3] = 0; - } else if (pd_gains == 2) { - pcinfo->pwr[1][3] = (val >> 4) & 0xf; - pcinfo->pddac[1][3] = (val >> 8) & 0x3f; - } - - if (pd_gains > 3) { - pcinfo->pwr_i[3] = (val >> 14) & 0x3; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2; - - pcinfo->pddac_i[3] = (val >> 3) & 0x7f; - pcinfo->pwr[3][0] = (val >> 10) & 0xf; - pcinfo->pddac[3][0] = (val >> 14) & 0x3; - - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac[3][0] |= (val & 0xF) << 2; - pcinfo->pwr[3][1] = (val >> 4) & 0xf; - pcinfo->pddac[3][1] = (val >> 8) & 0x3f; - - pcinfo->pwr[3][2] = (val >> 14) & 0x3; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2; - - pcinfo->pddac[3][2] = (val >> 2) & 0x3f; - pcinfo->pwr[3][3] = (val >> 8) & 0xf; - - pcinfo->pddac[3][3] = (val >> 12) & 0xF; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4; - } else if (pd_gains == 3) { - pcinfo->pwr[2][3] = (val >> 14) & 0x3; - AR5K_EEPROM_READ(offset++, val); - pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2; - - pcinfo->pddac[2][3] = (val >> 2) & 0x3f; - } - } - - return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo); -} - - -/* - * Read per rate target power (this is the maximum tx power - * supported by the card). This info is used when setting - * tx power, no matter the channel. - * - * This also works for v5 EEPROMs. - */ -static int -ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_rate_pcal_info *rate_pcal_info; - u8 *rate_target_pwr_num; - u32 offset; - u16 val; - int i; - - offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); - rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; - switch (mode) { - case AR5K_EEPROM_MODE_11A: - offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); - rate_pcal_info = ee->ee_rate_tpwr_a; - ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; - break; - case AR5K_EEPROM_MODE_11B: - offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); - rate_pcal_info = ee->ee_rate_tpwr_b; - ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */ - break; - case AR5K_EEPROM_MODE_11G: - offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version); - rate_pcal_info = ee->ee_rate_tpwr_g; - ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN; - break; - default: - return -EINVAL; - } - - /* Different freq mask for older eeproms (<= v3.2) */ - if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) { - for (i = 0; i < (*rate_target_pwr_num); i++) { - AR5K_EEPROM_READ(offset++, val); - rate_pcal_info[i].freq = - ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode); - - rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f); - rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f; - - AR5K_EEPROM_READ(offset++, val); - - if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || - val == 0) { - (*rate_target_pwr_num) = i; - break; - } - - rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7); - rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f); - rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f); - } - } else { - for (i = 0; i < (*rate_target_pwr_num); i++) { - AR5K_EEPROM_READ(offset++, val); - rate_pcal_info[i].freq = - ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode); - - rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f); - rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f; - - AR5K_EEPROM_READ(offset++, val); - - if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS || - val == 0) { - (*rate_target_pwr_num) = i; - break; - } - - rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf; - rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f); - rate_pcal_info[i].target_power_54 = (val & 0x3f); - } - } - - return 0; -} - - -/* - * Read per channel calibration info from EEPROM - * - * This info is used to calibrate the baseband power table. Imagine - * that for each channel there is a power curve that's hw specific - * (depends on amplifier etc) and we try to "correct" this curve using - * offsets we pass on to phy chip (baseband -> before amplifier) so that - * it can use accurate power values when setting tx power (takes amplifier's - * performance on each channel into account). - * - * EEPROM provides us with the offsets for some pre-calibrated channels - * and we have to interpolate to create the full table for these channels and - * also the table for any channel. - */ -static int -ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - int (*read_pcal)(struct ath5k_hw *hw, int mode); - int mode; - int err; - - if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) && - (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1)) - read_pcal = ath5k_eeprom_read_pcal_info_5112; - else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) && - (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2)) - read_pcal = ath5k_eeprom_read_pcal_info_2413; - else - read_pcal = ath5k_eeprom_read_pcal_info_5111; - - - for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; - mode++) { - err = read_pcal(ah, mode); - if (err) - return err; - - err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode); - if (err < 0) - return err; - } - - return 0; -} - -/* Read conformance test limits used for regulatory control */ -static int -ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_edge_power *rep; - unsigned int fmask, pmask; - unsigned int ctl_mode; - int i, j; - u32 offset; - u16 val; - - pmask = AR5K_EEPROM_POWER_M; - fmask = AR5K_EEPROM_FREQ_M(ee->ee_version); - offset = AR5K_EEPROM_CTL(ee->ee_version); - ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version); - for (i = 0; i < ee->ee_ctls; i += 2) { - AR5K_EEPROM_READ(offset++, val); - ee->ee_ctl[i] = (val >> 8) & 0xff; - ee->ee_ctl[i + 1] = val & 0xff; - } - - offset = AR5K_EEPROM_GROUP8_OFFSET; - if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0) - offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) - - AR5K_EEPROM_GROUP5_OFFSET; - else - offset += AR5K_EEPROM_GROUPS_START(ee->ee_version); - - rep = ee->ee_ctl_pwr; - for (i = 0; i < ee->ee_ctls; i++) { - switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) { - case AR5K_CTL_11A: - case AR5K_CTL_TURBO: - ctl_mode = AR5K_EEPROM_MODE_11A; - break; - default: - ctl_mode = AR5K_EEPROM_MODE_11G; - break; - } - if (ee->ee_ctl[i] == 0) { - if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) - offset += 8; - else - offset += 7; - rep += AR5K_EEPROM_N_EDGES; - continue; - } - if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) { - for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { - AR5K_EEPROM_READ(offset++, val); - rep[j].freq = (val >> 8) & fmask; - rep[j + 1].freq = val & fmask; - } - for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) { - AR5K_EEPROM_READ(offset++, val); - rep[j].edge = (val >> 8) & pmask; - rep[j].flag = (val >> 14) & 1; - rep[j + 1].edge = val & pmask; - rep[j + 1].flag = (val >> 6) & 1; - } - } else { - AR5K_EEPROM_READ(offset++, val); - rep[0].freq = (val >> 9) & fmask; - rep[1].freq = (val >> 2) & fmask; - rep[2].freq = (val << 5) & fmask; - - AR5K_EEPROM_READ(offset++, val); - rep[2].freq |= (val >> 11) & 0x1f; - rep[3].freq = (val >> 4) & fmask; - rep[4].freq = (val << 3) & fmask; - - AR5K_EEPROM_READ(offset++, val); - rep[4].freq |= (val >> 13) & 0x7; - rep[5].freq = (val >> 6) & fmask; - rep[6].freq = (val << 1) & fmask; - - AR5K_EEPROM_READ(offset++, val); - rep[6].freq |= (val >> 15) & 0x1; - rep[7].freq = (val >> 8) & fmask; - - rep[0].edge = (val >> 2) & pmask; - rep[1].edge = (val << 4) & pmask; - - AR5K_EEPROM_READ(offset++, val); - rep[1].edge |= (val >> 12) & 0xf; - rep[2].edge = (val >> 6) & pmask; - rep[3].edge = val & pmask; - - AR5K_EEPROM_READ(offset++, val); - rep[4].edge = (val >> 10) & pmask; - rep[5].edge = (val >> 4) & pmask; - rep[6].edge = (val << 2) & pmask; - - AR5K_EEPROM_READ(offset++, val); - rep[6].edge |= (val >> 14) & 0x3; - rep[7].edge = (val >> 8) & pmask; - } - for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) { - rep[j].freq = ath5k_eeprom_bin2freq(ee, - rep[j].freq, ctl_mode); - } - rep += AR5K_EEPROM_N_EDGES; - } - - return 0; -} - -static int -ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 offset; - u16 val; - int ret = 0, i; - - offset = AR5K_EEPROM_CTL(ee->ee_version) + - AR5K_EEPROM_N_CTLS(ee->ee_version); - - if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) { - /* No spur info for 5GHz */ - ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR; - /* 2 channels for 2GHz (2464/2420) */ - ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1; - ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2; - ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR; - } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) { - for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { - AR5K_EEPROM_READ(offset, val); - ee->ee_spur_chans[i][0] = val; - AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS, - val); - ee->ee_spur_chans[i][1] = val; - offset++; - } - } - - return ret; -} - - -/***********************\ -* Init/Detach functions * -\***********************/ - -/* - * Initialize eeprom data structure - */ -int -ath5k_eeprom_init(struct ath5k_hw *ah) -{ - int err; - - err = ath5k_eeprom_init_header(ah); - if (err < 0) - return err; - - err = ath5k_eeprom_init_modes(ah); - if (err < 0) - return err; - - err = ath5k_eeprom_read_pcal_info(ah); - if (err < 0) - return err; - - err = ath5k_eeprom_read_ctl_info(ah); - if (err < 0) - return err; - - err = ath5k_eeprom_read_spur_chans(ah); - if (err < 0) - return err; - - return 0; -} - -void -ath5k_eeprom_detach(struct ath5k_hw *ah) -{ - u8 mode; - - for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) - ath5k_eeprom_free_pcal_info(ah, mode); -} - -int -ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) -{ - switch (channel->hw_value) { - case AR5K_MODE_11A: - return AR5K_EEPROM_MODE_11A; - case AR5K_MODE_11G: - return AR5K_EEPROM_MODE_11G; - case AR5K_MODE_11B: - return AR5K_EEPROM_MODE_11B; - default: - return -1; - } -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/eeprom.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/eeprom.h deleted file mode 100644 index dc2bcfea..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/eeprom.h +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/* - * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE) - */ -#define AR5K_EEPROM_PCIE_OFFSET 0x02 /* Contains offset to PCI-E infos */ -#define AR5K_EEPROM_PCIE_SERDES_SECTION 0x40 /* PCIE_OFFSET points here when - * SERDES infos are present */ -#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ -#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ - -#define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ - -#define AR5K_EEPROM_RFKILL 0x0f -#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c -#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2 -#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002 -#define AR5K_EEPROM_RFKILL_POLARITY_S 1 - -#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ - -/* FLASH(EEPROM) Defines for AR531X chips */ -#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */ -#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */ -#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0 -#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4 -#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12 - -#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ -#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ -#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) -#define AR5K_EEPROM_INFO_CKSUM 0xffff -#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n)) - -#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */ -#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */ -#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2GHz (ar5211_rfregs) */ -#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ -#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ -#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */ -#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */ -#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */ -#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */ -#define AR5K_EEPROM_VERSION_4_3 0x4003 /* power calibration changes */ -#define AR5K_EEPROM_VERSION_4_4 0x4004 -#define AR5K_EEPROM_VERSION_4_5 0x4005 -#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */ -#define AR5K_EEPROM_VERSION_4_7 0x3007 /* 4007 ? */ -#define AR5K_EEPROM_VERSION_4_9 0x4009 /* EAR futureproofing */ -#define AR5K_EEPROM_VERSION_5_0 0x5000 /* Has 2413 PDADC calibration etc */ -#define AR5K_EEPROM_VERSION_5_1 0x5001 /* Has capability values */ -#define AR5K_EEPROM_VERSION_5_3 0x5003 /* Has spur mitigation tables */ - -#define AR5K_EEPROM_MODE_11A 0 -#define AR5K_EEPROM_MODE_11B 1 -#define AR5K_EEPROM_MODE_11G 2 - -#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */ -#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) -#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) -#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) -#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2GHz */ -#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */ -#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */ -#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ -#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5GHz */ - -/* Newer EEPROMs are using a different offset */ -#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \ - (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) - -#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3) -#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((s8)(((_v) >> 8) & 0xff)) -#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((s8)((_v) & 0xff)) - -/* Misc values available since EEPROM 4.0 */ -#define AR5K_EEPROM_MISC0 AR5K_EEPROM_INFO(4) -#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff) -#define AR5K_EEPROM_HDR_XR2_DIS(_v) (((_v) >> 12) & 0x1) -#define AR5K_EEPROM_HDR_XR5_DIS(_v) (((_v) >> 13) & 0x1) -#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3) - -#define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) -#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) -#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) /* has 32KHz crystal for sleep mode */ -#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) - -#define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) -#define AR5K_EEPROM_EEP_FILE_VERSION(_v) (((_v) >> 8) & 0xff) -#define AR5K_EEPROM_EAR_FILE_VERSION(_v) ((_v) & 0xff) - -#define AR5K_EEPROM_MISC3 AR5K_EEPROM_INFO(7) -#define AR5K_EEPROM_ART_BUILD_NUM(_v) (((_v) >> 10) & 0x3f) -#define AR5K_EEPROM_EAR_FILE_ID(_v) ((_v) & 0xff) - -#define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) -#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) -#define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) /* modes supported by radio 0 (bit 1: G, bit 2: A) */ -#define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) /* modes supported by radio 1 (bit 1: G, bit 2: A) */ - -#define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) -#define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) /* disable compression */ -#define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) /* disable AES */ -#define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */ -#define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */ -#define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */ -#define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heavy clipping */ -#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */ - -#define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) -#define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x7) /* MIMO chains disabled for TX bitmask */ -#define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x7) /* MIMO chains disabled for RX bitmask */ -#define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) /* 5.47-5.7GHz supported */ -#define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) /* Japan UNII1 band (5.15-5.25GHz) on even channels (5180, 5200, 5220, 5240) supported */ -#define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) /* Japan UNII2 band (5.25-5.35GHz) supported */ -#define AR5K_EEPROM_JAP_MID_EN (((_v) >> 9) & 0x1) /* Japan band from 5.47-5.7GHz supported */ -#define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 10) & 0x1) /* Japan UNII2 band (5.15-5.25GHz) on odd channels (5170, 5190, 5210, 5230) supported */ -#define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 11) & 0x1) /* Japan A mode enabled (using even channels) */ - -/* calibration settings */ -#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) -#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2) -#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d) -#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */ -#define AR5K_EEPROM_GROUPS_START(_v) AR5K_EEPROM_OFF(_v, 0x0100, 0x0150) /* Start of Groups */ -#define AR5K_EEPROM_GROUP1_OFFSET 0x0 -#define AR5K_EEPROM_GROUP2_OFFSET 0x5 -#define AR5K_EEPROM_GROUP3_OFFSET 0x37 -#define AR5K_EEPROM_GROUP4_OFFSET 0x46 -#define AR5K_EEPROM_GROUP5_OFFSET 0x55 -#define AR5K_EEPROM_GROUP6_OFFSET 0x65 -#define AR5K_EEPROM_GROUP7_OFFSET 0x69 -#define AR5K_EEPROM_GROUP8_OFFSET 0x6f - -#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ - AR5K_EEPROM_GROUP5_OFFSET, 0x0000) -#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ - AR5K_EEPROM_GROUP6_OFFSET, 0x0010) -#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v) AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \ - AR5K_EEPROM_GROUP7_OFFSET, 0x0014) - -/* [3.1 - 3.3] */ -#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec -#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed - -#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */ -#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */ -#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */ -#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */ -#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008 -#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */ -#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020 -#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */ -#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080 -#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */ -#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200 -#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */ -#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800 -#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */ -#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000 -#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */ -#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000 - -/* Some EEPROM defines */ -#define AR5K_EEPROM_EEP_SCALE 100 -#define AR5K_EEPROM_EEP_DELTA 10 -#define AR5K_EEPROM_N_MODES 3 -#define AR5K_EEPROM_N_5GHZ_CHAN 10 -#define AR5K_EEPROM_N_2GHZ_CHAN 3 -#define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 -#define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 -#define AR5K_EEPROM_MAX_CHAN 10 -#define AR5K_EEPROM_N_PWR_POINTS_5111 11 -#define AR5K_EEPROM_N_PCDAC 11 -#define AR5K_EEPROM_N_PHASE_CAL 5 -#define AR5K_EEPROM_N_TEST_FREQ 8 -#define AR5K_EEPROM_N_EDGES 8 -#define AR5K_EEPROM_N_INTERCEPTS 11 -#define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff) -#define AR5K_EEPROM_PCDAC_M 0x3f -#define AR5K_EEPROM_PCDAC_START 1 -#define AR5K_EEPROM_PCDAC_STOP 63 -#define AR5K_EEPROM_PCDAC_STEP 1 -#define AR5K_EEPROM_NON_EDGE_M 0x40 -#define AR5K_EEPROM_CHANNEL_POWER 8 -#define AR5K_EEPROM_N_OBDB 4 -#define AR5K_EEPROM_OBDB_DIS 0xffff -#define AR5K_EEPROM_CHANNEL_DIS 0xff -#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10) -#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32) -#define AR5K_EEPROM_MAX_CTLS 32 -#define AR5K_EEPROM_N_PD_CURVES 4 -#define AR5K_EEPROM_N_XPD0_POINTS 4 -#define AR5K_EEPROM_N_XPD3_POINTS 3 -#define AR5K_EEPROM_N_PD_GAINS 4 -#define AR5K_EEPROM_N_PD_POINTS 5 -#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35 -#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55 -#define AR5K_EEPROM_POWER_M 0x3f -#define AR5K_EEPROM_POWER_MIN 0 -#define AR5K_EEPROM_POWER_MAX 3150 -#define AR5K_EEPROM_POWER_STEP 50 -#define AR5K_EEPROM_POWER_TABLE_SIZE 64 -#define AR5K_EEPROM_N_POWER_LOC_11B 4 -#define AR5K_EEPROM_N_POWER_LOC_11G 6 -#define AR5K_EEPROM_I_GAIN 10 -#define AR5K_EEPROM_CCK_OFDM_DELTA 15 -#define AR5K_EEPROM_N_IQ_CAL 2 -/* 5GHz/2GHz */ -enum ath5k_eeprom_freq_bands { - AR5K_EEPROM_BAND_5GHZ = 0, - AR5K_EEPROM_BAND_2GHZ = 1, - AR5K_EEPROM_N_FREQ_BANDS, -}; -/* Spur chans per freq band */ -#define AR5K_EEPROM_N_SPUR_CHANS 5 -/* fbin value for chan 2464 x2 */ -#define AR5K_EEPROM_5413_SPUR_CHAN_1 1640 -/* fbin value for chan 2420 x2 */ -#define AR5K_EEPROM_5413_SPUR_CHAN_2 1200 -#define AR5K_EEPROM_SPUR_CHAN_MASK 0x3FFF -#define AR5K_EEPROM_NO_SPUR 0x8000 -#define AR5K_SPUR_CHAN_WIDTH 87 -#define AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz 3125 -#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250 - -#define AR5K_EEPROM_READ(_o, _v) do { \ - if (!ath5k_hw_nvram_read(ah, (_o), &(_v))) \ - return -EIO; \ -} while (0) - -#define AR5K_EEPROM_READ_HDR(_o, _v) \ - AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ - -enum ath5k_ant_table { - AR5K_ANT_CTL = 0, /* Idle switch table settings */ - AR5K_ANT_SWTABLE_A = 1, /* Switch table for antenna A */ - AR5K_ANT_SWTABLE_B = 2, /* Switch table for antenna B */ - AR5K_ANT_MAX, -}; - -enum ath5k_ctl_mode { - AR5K_CTL_11A = 0, - AR5K_CTL_11B = 1, - AR5K_CTL_11G = 2, - AR5K_CTL_TURBO = 3, - AR5K_CTL_TURBOG = 4, - AR5K_CTL_2GHT20 = 5, - AR5K_CTL_5GHT20 = 6, - AR5K_CTL_2GHT40 = 7, - AR5K_CTL_5GHT40 = 8, - AR5K_CTL_MODE_M = 15, -}; - -/* Per channel calibration data, used for power table setup */ -struct ath5k_chan_pcal_info_rf5111 { - /* Power levels in half dBm units - * for one power curve. */ - u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111]; - /* PCDAC table steps - * for the above values */ - u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111]; - /* Starting PCDAC step */ - u8 pcdac_min; - /* Final PCDAC step */ - u8 pcdac_max; -}; - -struct ath5k_chan_pcal_info_rf5112 { - /* Power levels in quarter dBm units - * for lower (0) and higher (3) - * level curves in 0.25dB units */ - s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS]; - s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS]; - /* PCDAC table steps - * for the above values */ - u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS]; - u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS]; -}; - -struct ath5k_chan_pcal_info_rf2413 { - /* Starting pwr/pddac values */ - s8 pwr_i[AR5K_EEPROM_N_PD_GAINS]; - u8 pddac_i[AR5K_EEPROM_N_PD_GAINS]; - /* (pwr,pddac) points - * power levels in 0.5dB units */ - s8 pwr[AR5K_EEPROM_N_PD_GAINS] - [AR5K_EEPROM_N_PD_POINTS]; - u8 pddac[AR5K_EEPROM_N_PD_GAINS] - [AR5K_EEPROM_N_PD_POINTS]; -}; - -enum ath5k_powertable_type { - AR5K_PWRTABLE_PWR_TO_PCDAC = 0, - AR5K_PWRTABLE_LINEAR_PCDAC = 1, - AR5K_PWRTABLE_PWR_TO_PDADC = 2, -}; - -struct ath5k_pdgain_info { - u8 pd_points; - u8 *pd_step; - /* Power values are in - * 0.25dB units */ - s16 *pd_pwr; -}; - -struct ath5k_chan_pcal_info { - /* Frequency */ - u16 freq; - /* Tx power boundaries */ - s16 max_pwr; - s16 min_pwr; - union { - struct ath5k_chan_pcal_info_rf5111 rf5111_info; - struct ath5k_chan_pcal_info_rf5112 rf5112_info; - struct ath5k_chan_pcal_info_rf2413 rf2413_info; - }; - /* Raw values used by phy code - * Curves are stored in order from lower - * gain to higher gain (max txpower -> min txpower) */ - struct ath5k_pdgain_info *pd_curves; -}; - -/* Per rate calibration data for each mode, - * used for rate power table setup. - * Note: Values in 0.5dB units */ -struct ath5k_rate_pcal_info { - u16 freq; /* Frequency */ - /* Power level for 6-24Mbit/s rates or - * 1Mb rate */ - u16 target_power_6to24; - /* Power level for 36Mbit rate or - * 2Mb rate */ - u16 target_power_36; - /* Power level for 48Mbit rate or - * 5.5Mbit rate */ - u16 target_power_48; - /* Power level for 54Mbit rate or - * 11Mbit rate */ - u16 target_power_54; -}; - -/* Power edges for conformance test limits */ -struct ath5k_edge_power { - u16 freq; - u16 edge; /* in half dBm */ - bool flag; -}; - -/** - * struct ath5k_eeprom_info - EEPROM calibration data - * - * @ee_regdomain: ath/regd.c takes care of COUNTRY_ERD and WORLDWIDE_ROAMING - * flags - * @ee_ant_gain: Antenna gain in 0.5dB steps signed [5211 only?] - * @ee_cck_ofdm_gain_delta: difference in gainF to output the same power for - * OFDM and CCK packets - * @ee_cck_ofdm_power_delta: power difference between OFDM (6Mbps) and CCK - * (11Mbps) rate in G mode. 0.1dB steps - * @ee_scaled_cck_delta: for Japan Channel 14: 0.1dB resolution - * - * @ee_i_cal: Initial I coefficient to correct I/Q mismatch in the receive path - * @ee_q_cal: Initial Q coefficient to correct I/Q mismatch in the receive path - * @ee_fixed_bias: use ee_ob and ee_db settings or use automatic control - * @ee_switch_settling: RX/TX Switch settling time - * @ee_atn_tx_rx: Difference in attenuation between TX and RX in 1dB steps - * @ee_ant_control: Antenna Control Settings - * @ee_ob: Bias current for Output stage of PA - * B/G mode: Index [0] is used for AR2112/5112, otherwise [1] - * A mode: [0] 5.15-5.25 [1] 5.25-5.50 [2] 5.50-5.70 [3] 5.70-5.85 GHz - * @ee_db: Bias current for Output stage of PA. see @ee_ob - * @ee_tx_end2xlna_enable: Time difference from when BB finishes sending a frame - * to when the external LNA is activated - * @ee_tx_end2xpa_disable: Time difference from when BB finishes sending a frame - * to when the external PA switch is deactivated - * @ee_tx_frm2xpa_enable: Time difference from when MAC sends frame to when - * external PA switch is activated - * @ee_thr_62: Clear Channel Assessment (CCA) sensitivity - * (IEEE802.11a section 17.3.10.5 ) - * @ee_xlna_gain: Total gain of the LNA (information only) - * @ee_xpd: Use external (1) or internal power detector - * @ee_x_gain: Gain for external power detector output (differences in EEMAP - * versions!) - * @ee_i_gain: Initial gain value after reset - * @ee_margin_tx_rx: Margin in dB when final attenuation stage should be used - * - * @ee_false_detect: Backoff in Sensitivity (dB) on channels with spur signals - * @ee_noise_floor_thr: Noise floor threshold in 1dB steps - * @ee_adc_desired_size: Desired amplitude for ADC, used by AGC; in 0.5 dB steps - * @ee_pga_desired_size: Desired output of PGA (for BB gain) in 0.5 dB steps - * @ee_pd_gain_overlap: PD ADC curves need to overlap in 0.5dB steps (ee_map>=2) - */ -struct ath5k_eeprom_info { - - /* Header information */ - u16 ee_magic; - u16 ee_protect; - u16 ee_regdomain; - u16 ee_version; - u16 ee_header; - u16 ee_ant_gain; - u8 ee_rfkill_pin; - bool ee_rfkill_pol; - bool ee_is_hb63; - bool ee_serdes; - u16 ee_misc0; - u16 ee_misc1; - u16 ee_misc2; - u16 ee_misc3; - u16 ee_misc4; - u16 ee_misc5; - u16 ee_misc6; - u16 ee_cck_ofdm_gain_delta; - u16 ee_cck_ofdm_power_delta; - u16 ee_scaled_cck_delta; - - /* RF Calibration settings (reset, rfregs) */ - u16 ee_i_cal[AR5K_EEPROM_N_MODES]; - u16 ee_q_cal[AR5K_EEPROM_N_MODES]; - u16 ee_fixed_bias[AR5K_EEPROM_N_MODES]; - u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]; - u16 ee_xr_power[AR5K_EEPROM_N_MODES]; - u16 ee_switch_settling[AR5K_EEPROM_N_MODES]; - u16 ee_atn_tx_rx[AR5K_EEPROM_N_MODES]; - u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]; - u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; - u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; - u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES]; - u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES]; - u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES]; - u16 ee_thr_62[AR5K_EEPROM_N_MODES]; - u16 ee_xlna_gain[AR5K_EEPROM_N_MODES]; - u16 ee_xpd[AR5K_EEPROM_N_MODES]; - u16 ee_x_gain[AR5K_EEPROM_N_MODES]; - u16 ee_i_gain[AR5K_EEPROM_N_MODES]; - u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]; - u16 ee_switch_settling_turbo[AR5K_EEPROM_N_MODES]; - u16 ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES]; - u16 ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES]; - - /* Power calibration data */ - u16 ee_false_detect[AR5K_EEPROM_N_MODES]; - - /* Number of pd gain curves per mode */ - u8 ee_pd_gains[AR5K_EEPROM_N_MODES]; - /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */ - u8 ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS]; - - u8 ee_n_piers[AR5K_EEPROM_N_MODES]; - struct ath5k_chan_pcal_info ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN]; - struct ath5k_chan_pcal_info ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; - struct ath5k_chan_pcal_info ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; - - /* Per rate target power levels */ - u8 ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES]; - struct ath5k_rate_pcal_info ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN]; - struct ath5k_rate_pcal_info ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; - struct ath5k_rate_pcal_info ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX]; - - /* Conformance test limits (Unused) */ - u8 ee_ctls; - u8 ee_ctl[AR5K_EEPROM_MAX_CTLS]; - struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS]; - - /* Noise Floor Calibration settings */ - s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]; - s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]; - s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]; - s8 ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES]; - s8 ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES]; - s8 ee_pd_gain_overlap; - - /* Spur mitigation data (fbin values for spur channels) */ - u16 ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS]; - - /* Antenna raw switch tables */ - u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; -}; - -int -ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel); diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/gpio.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/gpio.c deleted file mode 100644 index 73d3dd8a..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/gpio.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/****************\ - GPIO Functions -\****************/ - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - - -/** - * DOC: GPIO/LED functions - * - * Here we control the 6 bidirectional GPIO pins provided by the hw. - * We can set a GPIO pin to be an input or an output pin on GPIO control - * register and then read or set its status from GPIO data input/output - * registers. - * - * We also control the two LED pins provided by the hw, LED_0 is our - * "power" LED and LED_1 is our "network activity" LED but many scenarios - * are available from hw. Vendors might also provide LEDs connected to the - * GPIO pins, we handle them through the LED subsystem on led.c - */ - - -/** - * ath5k_hw_set_ledstate() - Set led state - * @ah: The &struct ath5k_hw - * @state: One of AR5K_LED_* - * - * Used to set the LED blinking state. This only - * works for the LED connected to the LED_0, LED_1 pins, - * not the GPIO based. - */ -void -ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) -{ - u32 led; - /*5210 has different led mode handling*/ - u32 led_5210; - - /*Reset led status*/ - if (ah->ah_version != AR5K_AR5210) - AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED); - else - AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED); - - /* - * Some blinking values, define at your wish - */ - switch (state) { - case AR5K_LED_SCAN: - case AR5K_LED_AUTH: - led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND; - led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL; - break; - - case AR5K_LED_INIT: - led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE; - led_5210 = AR5K_PCICFG_LED_PEND; - break; - - case AR5K_LED_ASSOC: - case AR5K_LED_RUN: - led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC; - led_5210 = AR5K_PCICFG_LED_ASSOC; - break; - - default: - led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE; - led_5210 = AR5K_PCICFG_LED_PEND; - break; - } - - /*Write new status to the register*/ - if (ah->ah_version != AR5K_AR5210) - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led); - else - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210); -} - -/** - * ath5k_hw_set_gpio_input() - Set GPIO inputs - * @ah: The &struct ath5k_hw - * @gpio: GPIO pin to set as input - */ -int -ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) -{ - if (gpio >= AR5K_NUM_GPIO) - return -EINVAL; - - ath5k_hw_reg_write(ah, - (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) - | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR); - - return 0; -} - -/** - * ath5k_hw_set_gpio_output() - Set GPIO outputs - * @ah: The &struct ath5k_hw - * @gpio: The GPIO pin to set as output - */ -int -ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) -{ - if (gpio >= AR5K_NUM_GPIO) - return -EINVAL; - - ath5k_hw_reg_write(ah, - (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) - | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR); - - return 0; -} - -/** - * ath5k_hw_get_gpio() - Get GPIO state - * @ah: The &struct ath5k_hw - * @gpio: The GPIO pin to read - */ -u32 -ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) -{ - if (gpio >= AR5K_NUM_GPIO) - return 0xffffffff; - - /* GPIO input magic */ - return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) & - 0x1; -} - -/** - * ath5k_hw_set_gpio() - Set GPIO state - * @ah: The &struct ath5k_hw - * @gpio: The GPIO pin to set - * @val: Value to set (boolean) - */ -int -ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) -{ - u32 data; - - if (gpio >= AR5K_NUM_GPIO) - return -EINVAL; - - /* GPIO output magic */ - data = ath5k_hw_reg_read(ah, AR5K_GPIODO); - - data &= ~(1 << gpio); - data |= (val & 1) << gpio; - - ath5k_hw_reg_write(ah, data, AR5K_GPIODO); - - return 0; -} - -/** - * ath5k_hw_set_gpio_intr() - Initialize the GPIO interrupt (RFKill switch) - * @ah: The &struct ath5k_hw - * @gpio: The GPIO pin to use - * @interrupt_level: True to generate interrupt on active pin (high) - * - * This function is used to set up the GPIO interrupt for the hw RFKill switch. - * That switch is connected to a GPIO pin and it's number is stored on EEPROM. - * It can either open or close the circuit to indicate that we should disable - * RF/Wireless to save power (we also get that from EEPROM). - */ -void -ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, - u32 interrupt_level) -{ - u32 data; - - if (gpio >= AR5K_NUM_GPIO) - return; - - /* - * Set the GPIO interrupt - */ - data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & - ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH | - AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) | - (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA); - - ath5k_hw_reg_write(ah, interrupt_level ? data : - (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR); - - ah->ah_imr |= AR5K_IMR_GPIO; - - /* Enable GPIO interrupts */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO); -} - diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/initvals.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/initvals.c deleted file mode 100644 index a1ea78e0..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/initvals.c +++ /dev/null @@ -1,1604 +0,0 @@ -/* - * Initial register settings functions - * - * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> - * - * Permission to use, copy, modify, and 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 "ath5k.h" -#include "reg.h" -#include "debug.h" - -/** - * struct ath5k_ini - Mode-independent initial register writes - * @ini_register: Register address - * @ini_value: Default value - * @ini_mode: 0 to write 1 to read (and clear) - */ -struct ath5k_ini { - u16 ini_register; - u32 ini_value; - - enum { - AR5K_INI_WRITE = 0, /* Default */ - AR5K_INI_READ = 1, - } ini_mode; -}; - -/** - * struct ath5k_ini_mode - Mode specific initial register values - * @mode_register: Register address - * @mode_value: Set of values for each enum ath5k_driver_mode - */ -struct ath5k_ini_mode { - u16 mode_register; - u32 mode_value[3]; -}; - -/* Initial register settings for AR5210 */ -static const struct ath5k_ini ar5210_ini[] = { - /* PCU and MAC registers */ - { AR5K_NOQCU_TXDP0, 0 }, - { AR5K_NOQCU_TXDP1, 0 }, - { AR5K_RXDP, 0 }, - { AR5K_CR, 0 }, - { AR5K_ISR, 0, AR5K_INI_READ }, - { AR5K_IMR, 0 }, - { AR5K_IER, AR5K_IER_DISABLE }, - { AR5K_BSR, 0, AR5K_INI_READ }, - { AR5K_TXCFG, AR5K_DMASIZE_128B }, - { AR5K_RXCFG, AR5K_DMASIZE_128B }, - { AR5K_CFG, AR5K_INIT_CFG }, - { AR5K_TOPS, 8 }, - { AR5K_RXNOFRM, 8 }, - { AR5K_RPGTO, 0 }, - { AR5K_TXNOFRM, 0 }, - { AR5K_SFR, 0 }, - { AR5K_MIBC, 0 }, - { AR5K_MISC, 0 }, - { AR5K_RX_FILTER_5210, 0 }, - { AR5K_MCAST_FILTER0_5210, 0 }, - { AR5K_MCAST_FILTER1_5210, 0 }, - { AR5K_TX_MASK0, 0 }, - { AR5K_TX_MASK1, 0 }, - { AR5K_CLR_TMASK, 0 }, - { AR5K_TRIG_LVL, AR5K_TUNE_MIN_TX_FIFO_THRES }, - { AR5K_DIAG_SW_5210, 0 }, - { AR5K_RSSI_THR, AR5K_TUNE_RSSI_THRES }, - { AR5K_TSF_L32_5210, 0 }, - { AR5K_TIMER0_5210, 0 }, - { AR5K_TIMER1_5210, 0xffffffff }, - { AR5K_TIMER2_5210, 0xffffffff }, - { AR5K_TIMER3_5210, 1 }, - { AR5K_CFP_DUR_5210, 0 }, - { AR5K_CFP_PERIOD_5210, 0 }, - /* PHY registers */ - { AR5K_PHY(0), 0x00000047 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY(3), 0x09848ea6 }, - { AR5K_PHY(4), 0x3d32e000 }, - { AR5K_PHY(5), 0x0000076b }, - { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE }, - { AR5K_PHY(8), 0x02020200 }, - { AR5K_PHY(9), 0x00000e0e }, - { AR5K_PHY(10), 0x0a020201 }, - { AR5K_PHY(11), 0x00036ffc }, - { AR5K_PHY(12), 0x00000000 }, - { AR5K_PHY(13), 0x00000e0e }, - { AR5K_PHY(14), 0x00000007 }, - { AR5K_PHY(15), 0x00020100 }, - { AR5K_PHY(16), 0x89630000 }, - { AR5K_PHY(17), 0x1372169c }, - { AR5K_PHY(18), 0x0018b633 }, - { AR5K_PHY(19), 0x1284613c }, - { AR5K_PHY(20), 0x0de8b8e0 }, - { AR5K_PHY(21), 0x00074859 }, - { AR5K_PHY(22), 0x7e80beba }, - { AR5K_PHY(23), 0x313a665e }, - { AR5K_PHY_AGCCTL, 0x00001d08 }, - { AR5K_PHY(25), 0x0001ce00 }, - { AR5K_PHY(26), 0x409a4190 }, - { AR5K_PHY(28), 0x0000000f }, - { AR5K_PHY(29), 0x00000080 }, - { AR5K_PHY(30), 0x00000004 }, - { AR5K_PHY(31), 0x00000018 }, /* 0x987c */ - { AR5K_PHY(64), 0x00000000 }, /* 0x9900 */ - { AR5K_PHY(65), 0x00000000 }, - { AR5K_PHY(66), 0x00000000 }, - { AR5K_PHY(67), 0x00800000 }, - { AR5K_PHY(68), 0x00000003 }, - /* BB gain table (64bytes) */ - { AR5K_BB_GAIN(0), 0x00000000 }, - { AR5K_BB_GAIN(1), 0x00000020 }, - { AR5K_BB_GAIN(2), 0x00000010 }, - { AR5K_BB_GAIN(3), 0x00000030 }, - { AR5K_BB_GAIN(4), 0x00000008 }, - { AR5K_BB_GAIN(5), 0x00000028 }, - { AR5K_BB_GAIN(6), 0x00000028 }, - { AR5K_BB_GAIN(7), 0x00000004 }, - { AR5K_BB_GAIN(8), 0x00000024 }, - { AR5K_BB_GAIN(9), 0x00000014 }, - { AR5K_BB_GAIN(10), 0x00000034 }, - { AR5K_BB_GAIN(11), 0x0000000c }, - { AR5K_BB_GAIN(12), 0x0000002c }, - { AR5K_BB_GAIN(13), 0x00000002 }, - { AR5K_BB_GAIN(14), 0x00000022 }, - { AR5K_BB_GAIN(15), 0x00000012 }, - { AR5K_BB_GAIN(16), 0x00000032 }, - { AR5K_BB_GAIN(17), 0x0000000a }, - { AR5K_BB_GAIN(18), 0x0000002a }, - { AR5K_BB_GAIN(19), 0x00000001 }, - { AR5K_BB_GAIN(20), 0x00000021 }, - { AR5K_BB_GAIN(21), 0x00000011 }, - { AR5K_BB_GAIN(22), 0x00000031 }, - { AR5K_BB_GAIN(23), 0x00000009 }, - { AR5K_BB_GAIN(24), 0x00000029 }, - { AR5K_BB_GAIN(25), 0x00000005 }, - { AR5K_BB_GAIN(26), 0x00000025 }, - { AR5K_BB_GAIN(27), 0x00000015 }, - { AR5K_BB_GAIN(28), 0x00000035 }, - { AR5K_BB_GAIN(29), 0x0000000d }, - { AR5K_BB_GAIN(30), 0x0000002d }, - { AR5K_BB_GAIN(31), 0x00000003 }, - { AR5K_BB_GAIN(32), 0x00000023 }, - { AR5K_BB_GAIN(33), 0x00000013 }, - { AR5K_BB_GAIN(34), 0x00000033 }, - { AR5K_BB_GAIN(35), 0x0000000b }, - { AR5K_BB_GAIN(36), 0x0000002b }, - { AR5K_BB_GAIN(37), 0x00000007 }, - { AR5K_BB_GAIN(38), 0x00000027 }, - { AR5K_BB_GAIN(39), 0x00000017 }, - { AR5K_BB_GAIN(40), 0x00000037 }, - { AR5K_BB_GAIN(41), 0x0000000f }, - { AR5K_BB_GAIN(42), 0x0000002f }, - { AR5K_BB_GAIN(43), 0x0000002f }, - { AR5K_BB_GAIN(44), 0x0000002f }, - { AR5K_BB_GAIN(45), 0x0000002f }, - { AR5K_BB_GAIN(46), 0x0000002f }, - { AR5K_BB_GAIN(47), 0x0000002f }, - { AR5K_BB_GAIN(48), 0x0000002f }, - { AR5K_BB_GAIN(49), 0x0000002f }, - { AR5K_BB_GAIN(50), 0x0000002f }, - { AR5K_BB_GAIN(51), 0x0000002f }, - { AR5K_BB_GAIN(52), 0x0000002f }, - { AR5K_BB_GAIN(53), 0x0000002f }, - { AR5K_BB_GAIN(54), 0x0000002f }, - { AR5K_BB_GAIN(55), 0x0000002f }, - { AR5K_BB_GAIN(56), 0x0000002f }, - { AR5K_BB_GAIN(57), 0x0000002f }, - { AR5K_BB_GAIN(58), 0x0000002f }, - { AR5K_BB_GAIN(59), 0x0000002f }, - { AR5K_BB_GAIN(60), 0x0000002f }, - { AR5K_BB_GAIN(61), 0x0000002f }, - { AR5K_BB_GAIN(62), 0x0000002f }, - { AR5K_BB_GAIN(63), 0x0000002f }, - /* 5110 RF gain table (64btes) */ - { AR5K_RF_GAIN(0), 0x0000001d }, - { AR5K_RF_GAIN(1), 0x0000005d }, - { AR5K_RF_GAIN(2), 0x0000009d }, - { AR5K_RF_GAIN(3), 0x000000dd }, - { AR5K_RF_GAIN(4), 0x0000011d }, - { AR5K_RF_GAIN(5), 0x00000021 }, - { AR5K_RF_GAIN(6), 0x00000061 }, - { AR5K_RF_GAIN(7), 0x000000a1 }, - { AR5K_RF_GAIN(8), 0x000000e1 }, - { AR5K_RF_GAIN(9), 0x00000031 }, - { AR5K_RF_GAIN(10), 0x00000071 }, - { AR5K_RF_GAIN(11), 0x000000b1 }, - { AR5K_RF_GAIN(12), 0x0000001c }, - { AR5K_RF_GAIN(13), 0x0000005c }, - { AR5K_RF_GAIN(14), 0x00000029 }, - { AR5K_RF_GAIN(15), 0x00000069 }, - { AR5K_RF_GAIN(16), 0x000000a9 }, - { AR5K_RF_GAIN(17), 0x00000020 }, - { AR5K_RF_GAIN(18), 0x00000019 }, - { AR5K_RF_GAIN(19), 0x00000059 }, - { AR5K_RF_GAIN(20), 0x00000099 }, - { AR5K_RF_GAIN(21), 0x00000030 }, - { AR5K_RF_GAIN(22), 0x00000005 }, - { AR5K_RF_GAIN(23), 0x00000025 }, - { AR5K_RF_GAIN(24), 0x00000065 }, - { AR5K_RF_GAIN(25), 0x000000a5 }, - { AR5K_RF_GAIN(26), 0x00000028 }, - { AR5K_RF_GAIN(27), 0x00000068 }, - { AR5K_RF_GAIN(28), 0x0000001f }, - { AR5K_RF_GAIN(29), 0x0000001e }, - { AR5K_RF_GAIN(30), 0x00000018 }, - { AR5K_RF_GAIN(31), 0x00000058 }, - { AR5K_RF_GAIN(32), 0x00000098 }, - { AR5K_RF_GAIN(33), 0x00000003 }, - { AR5K_RF_GAIN(34), 0x00000004 }, - { AR5K_RF_GAIN(35), 0x00000044 }, - { AR5K_RF_GAIN(36), 0x00000084 }, - { AR5K_RF_GAIN(37), 0x00000013 }, - { AR5K_RF_GAIN(38), 0x00000012 }, - { AR5K_RF_GAIN(39), 0x00000052 }, - { AR5K_RF_GAIN(40), 0x00000092 }, - { AR5K_RF_GAIN(41), 0x000000d2 }, - { AR5K_RF_GAIN(42), 0x0000002b }, - { AR5K_RF_GAIN(43), 0x0000002a }, - { AR5K_RF_GAIN(44), 0x0000006a }, - { AR5K_RF_GAIN(45), 0x000000aa }, - { AR5K_RF_GAIN(46), 0x0000001b }, - { AR5K_RF_GAIN(47), 0x0000001a }, - { AR5K_RF_GAIN(48), 0x0000005a }, - { AR5K_RF_GAIN(49), 0x0000009a }, - { AR5K_RF_GAIN(50), 0x000000da }, - { AR5K_RF_GAIN(51), 0x00000006 }, - { AR5K_RF_GAIN(52), 0x00000006 }, - { AR5K_RF_GAIN(53), 0x00000006 }, - { AR5K_RF_GAIN(54), 0x00000006 }, - { AR5K_RF_GAIN(55), 0x00000006 }, - { AR5K_RF_GAIN(56), 0x00000006 }, - { AR5K_RF_GAIN(57), 0x00000006 }, - { AR5K_RF_GAIN(58), 0x00000006 }, - { AR5K_RF_GAIN(59), 0x00000006 }, - { AR5K_RF_GAIN(60), 0x00000006 }, - { AR5K_RF_GAIN(61), 0x00000006 }, - { AR5K_RF_GAIN(62), 0x00000006 }, - { AR5K_RF_GAIN(63), 0x00000006 }, - /* PHY activation */ - { AR5K_PHY(53), 0x00000020 }, - { AR5K_PHY(51), 0x00000004 }, - { AR5K_PHY(50), 0x00060106 }, - { AR5K_PHY(39), 0x0000006d }, - { AR5K_PHY(48), 0x00000000 }, - { AR5K_PHY(52), 0x00000014 }, - { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE }, -}; - -/* Initial register settings for AR5211 */ -static const struct ath5k_ini ar5211_ini[] = { - { AR5K_RXDP, 0x00000000 }, - { AR5K_RTSD0, 0x84849c9c }, - { AR5K_RTSD1, 0x7c7c7c7c }, - { AR5K_RXCFG, 0x00000005 }, - { AR5K_MIBC, 0x00000000 }, - { AR5K_TOPS, 0x00000008 }, - { AR5K_RXNOFRM, 0x00000008 }, - { AR5K_TXNOFRM, 0x00000010 }, - { AR5K_RPGTO, 0x00000000 }, - { AR5K_RFCNT, 0x0000001f }, - { AR5K_QUEUE_TXDP(0), 0x00000000 }, - { AR5K_QUEUE_TXDP(1), 0x00000000 }, - { AR5K_QUEUE_TXDP(2), 0x00000000 }, - { AR5K_QUEUE_TXDP(3), 0x00000000 }, - { AR5K_QUEUE_TXDP(4), 0x00000000 }, - { AR5K_QUEUE_TXDP(5), 0x00000000 }, - { AR5K_QUEUE_TXDP(6), 0x00000000 }, - { AR5K_QUEUE_TXDP(7), 0x00000000 }, - { AR5K_QUEUE_TXDP(8), 0x00000000 }, - { AR5K_QUEUE_TXDP(9), 0x00000000 }, - { AR5K_DCU_FP, 0x00000000 }, - { AR5K_STA_ID1, 0x00000000 }, - { AR5K_BSS_ID0, 0x00000000 }, - { AR5K_BSS_ID1, 0x00000000 }, - { AR5K_RSSI_THR, 0x00000000 }, - { AR5K_CFP_PERIOD_5211, 0x00000000 }, - { AR5K_TIMER0_5211, 0x00000030 }, - { AR5K_TIMER1_5211, 0x0007ffff }, - { AR5K_TIMER2_5211, 0x01ffffff }, - { AR5K_TIMER3_5211, 0x00000031 }, - { AR5K_CFP_DUR_5211, 0x00000000 }, - { AR5K_RX_FILTER_5211, 0x00000000 }, - { AR5K_MCAST_FILTER0_5211, 0x00000000 }, - { AR5K_MCAST_FILTER1_5211, 0x00000002 }, - { AR5K_DIAG_SW_5211, 0x00000000 }, - { AR5K_ADDAC_TEST, 0x00000000 }, - { AR5K_DEFAULT_ANTENNA, 0x00000000 }, - /* PHY registers */ - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY(3), 0x2d849093 }, - { AR5K_PHY(4), 0x7d32e000 }, - { AR5K_PHY(5), 0x00000f6b }, - { AR5K_PHY_ACT, 0x00000000 }, - { AR5K_PHY(11), 0x00026ffe }, - { AR5K_PHY(12), 0x00000000 }, - { AR5K_PHY(15), 0x00020100 }, - { AR5K_PHY(16), 0x206a017a }, - { AR5K_PHY(19), 0x1284613c }, - { AR5K_PHY(21), 0x00000859 }, - { AR5K_PHY(26), 0x409a4190 }, /* 0x9868 */ - { AR5K_PHY(27), 0x050cb081 }, - { AR5K_PHY(28), 0x0000000f }, - { AR5K_PHY(29), 0x00000080 }, - { AR5K_PHY(30), 0x0000000c }, - { AR5K_PHY(64), 0x00000000 }, - { AR5K_PHY(65), 0x00000000 }, - { AR5K_PHY(66), 0x00000000 }, - { AR5K_PHY(67), 0x00800000 }, - { AR5K_PHY(68), 0x00000001 }, - { AR5K_PHY(71), 0x0000092a }, - { AR5K_PHY_IQ, 0x00000000 }, - { AR5K_PHY(73), 0x00058a05 }, - { AR5K_PHY(74), 0x00000001 }, - { AR5K_PHY(75), 0x00000000 }, - { AR5K_PHY_PAPD_PROBE, 0x00000000 }, - { AR5K_PHY(77), 0x00000000 }, /* 0x9934 */ - { AR5K_PHY(78), 0x00000000 }, /* 0x9938 */ - { AR5K_PHY(79), 0x0000003f }, /* 0x993c */ - { AR5K_PHY(80), 0x00000004 }, - { AR5K_PHY(82), 0x00000000 }, - { AR5K_PHY(83), 0x00000000 }, - { AR5K_PHY(84), 0x00000000 }, - { AR5K_PHY_RADAR, 0x5d50f14c }, - { AR5K_PHY(86), 0x00000018 }, - { AR5K_PHY(87), 0x004b6a8e }, - /* Initial Power table (32bytes) - * common on all cards/modes. - * Note: Table is rewritten during - * txpower setup later using calibration - * data etc. so next write is non-common */ - { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff }, - { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff }, - { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff }, - { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff }, - { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff }, - { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff }, - { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff }, - { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff }, - { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff }, - { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff }, - { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff }, - { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff }, - { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff }, - { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff }, - { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff }, - { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff }, - { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff }, - { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff }, - { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff }, - { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff }, - { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff }, - { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff }, - { AR5K_PHY_CCKTXCTL, 0x00000000 }, - { AR5K_PHY(642), 0x503e4646 }, - { AR5K_PHY_GAIN_2GHZ, 0x6480416c }, - { AR5K_PHY(644), 0x0199a003 }, - { AR5K_PHY(645), 0x044cd610 }, - { AR5K_PHY(646), 0x13800040 }, - { AR5K_PHY(647), 0x1be00060 }, - { AR5K_PHY(648), 0x0c53800a }, - { AR5K_PHY(649), 0x0014df3b }, - { AR5K_PHY(650), 0x000001b5 }, - { AR5K_PHY(651), 0x00000020 }, -}; - -/* Initial mode-specific settings for AR5211 - * 5211 supports OFDM-only g (draft g) but we - * need to test it ! */ -static const struct ath5k_ini_mode ar5211_ini_mode[] = { - { AR5K_TXCFG, - /* A B G */ - { 0x00000015, 0x0000001d, 0x00000015 } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(0), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(1), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(2), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(3), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(4), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(5), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(6), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(7), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(8), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(9), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_DCU_GBL_IFS_SLOT, - { 0x00000168, 0x000001b8, 0x00000168 } }, - { AR5K_DCU_GBL_IFS_SIFS, - { 0x00000230, 0x000000b0, 0x00000230 } }, - { AR5K_DCU_GBL_IFS_EIFS, - { 0x00000d98, 0x00001f48, 0x00000d98 } }, - { AR5K_DCU_GBL_IFS_MISC, - { 0x0000a0e0, 0x00005880, 0x0000a0e0 } }, - { AR5K_TIME_OUT, - { 0x04000400, 0x20003000, 0x04000400 } }, - { AR5K_USEC_5211, - { 0x0e8d8fa7, 0x01608f95, 0x0e8d8fa7 } }, - { AR5K_PHY(8), - { 0x02020200, 0x02010200, 0x02020200 } }, - { AR5K_PHY_RF_CTL2, - { 0x00000e0e, 0x00000707, 0x00000e0e } }, - { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x05010000, 0x0a020001 } }, - { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, - { AR5K_PHY_PA_CTL, - { 0x00000007, 0x0000000b, 0x0000000b } }, - { AR5K_PHY_SETTLING, - { 0x1372169c, 0x137216a8, 0x1372169c } }, - { AR5K_PHY_GAIN, - { 0x0018ba67, 0x0018ba69, 0x0018ba69 } }, - { AR5K_PHY_DESIRED_SIZE, - { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } }, - { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } }, - { AR5K_PHY_AGCCOARSE, - { 0x31375d5e, 0x313a5d5e, 0x31375d5e } }, - { AR5K_PHY_AGCCTL, - { 0x0000bd10, 0x0000bd38, 0x0000bd10 } }, - { AR5K_PHY_NF, - { 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, - { AR5K_PHY_RX_DELAY, - { 0x00002710, 0x0000157c, 0x00002710 } }, - { AR5K_PHY(70), - { 0x00000190, 0x00000084, 0x00000190 } }, - { AR5K_PHY_FRAME_CTL_5211, - { 0x6fe01020, 0x6fe00920, 0x6fe01020 } }, - { AR5K_PHY_PCDAC_TXPOWER_BASE, - { 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } }, - { AR5K_RF_BUFFER_CONTROL_4, - { 0x00000010, 0x00000010, 0x00000010 } }, -}; - -/* Initial register settings for AR5212 and newer chips */ -static const struct ath5k_ini ar5212_ini_common_start[] = { - { AR5K_RXDP, 0x00000000 }, - { AR5K_RXCFG, 0x00000005 }, - { AR5K_MIBC, 0x00000000 }, - { AR5K_TOPS, 0x00000008 }, - { AR5K_RXNOFRM, 0x00000008 }, - { AR5K_TXNOFRM, 0x00000010 }, - { AR5K_RPGTO, 0x00000000 }, - { AR5K_RFCNT, 0x0000001f }, - { AR5K_QUEUE_TXDP(0), 0x00000000 }, - { AR5K_QUEUE_TXDP(1), 0x00000000 }, - { AR5K_QUEUE_TXDP(2), 0x00000000 }, - { AR5K_QUEUE_TXDP(3), 0x00000000 }, - { AR5K_QUEUE_TXDP(4), 0x00000000 }, - { AR5K_QUEUE_TXDP(5), 0x00000000 }, - { AR5K_QUEUE_TXDP(6), 0x00000000 }, - { AR5K_QUEUE_TXDP(7), 0x00000000 }, - { AR5K_QUEUE_TXDP(8), 0x00000000 }, - { AR5K_QUEUE_TXDP(9), 0x00000000 }, - { AR5K_DCU_FP, 0x00000000 }, - { AR5K_DCU_TXP, 0x00000000 }, - /* Tx filter table 0 (32 entries) */ - { AR5K_DCU_TX_FILTER_0(0), 0x00000000 }, /* DCU 0 */ - { AR5K_DCU_TX_FILTER_0(1), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(2), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(3), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(4), 0x00000000 }, /* DCU 1 */ - { AR5K_DCU_TX_FILTER_0(5), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(6), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(7), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(8), 0x00000000 }, /* DCU 2 */ - { AR5K_DCU_TX_FILTER_0(9), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(10), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(11), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */ - { AR5K_DCU_TX_FILTER_0(13), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(14), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(15), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */ - { AR5K_DCU_TX_FILTER_0(17), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(18), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(19), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */ - { AR5K_DCU_TX_FILTER_0(21), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(22), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(23), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */ - { AR5K_DCU_TX_FILTER_0(25), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(26), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(27), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */ - { AR5K_DCU_TX_FILTER_0(29), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(30), 0x00000000 }, - { AR5K_DCU_TX_FILTER_0(31), 0x00000000 }, - /* Tx filter table 1 (16 entries) */ - { AR5K_DCU_TX_FILTER_1(0), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(1), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(2), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(3), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(4), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(5), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(6), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(7), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(8), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(9), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(10), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(11), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(12), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(13), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(14), 0x00000000 }, - { AR5K_DCU_TX_FILTER_1(15), 0x00000000 }, - { AR5K_DCU_TX_FILTER_CLR, 0x00000000 }, - { AR5K_DCU_TX_FILTER_SET, 0x00000000 }, - { AR5K_STA_ID1, 0x00000000 }, - { AR5K_BSS_ID0, 0x00000000 }, - { AR5K_BSS_ID1, 0x00000000 }, - { AR5K_BEACON_5211, 0x00000000 }, - { AR5K_CFP_PERIOD_5211, 0x00000000 }, - { AR5K_TIMER0_5211, 0x00000030 }, - { AR5K_TIMER1_5211, 0x0007ffff }, - { AR5K_TIMER2_5211, 0x01ffffff }, - { AR5K_TIMER3_5211, 0x00000031 }, - { AR5K_CFP_DUR_5211, 0x00000000 }, - { AR5K_RX_FILTER_5211, 0x00000000 }, - { AR5K_DIAG_SW_5211, 0x00000000 }, - { AR5K_ADDAC_TEST, 0x00000000 }, - { AR5K_DEFAULT_ANTENNA, 0x00000000 }, - { AR5K_FRAME_CTL_QOSM, 0x000fc78f }, - { AR5K_XRMODE, 0x2a82301a }, - { AR5K_XRDELAY, 0x05dc01e0 }, - { AR5K_XRTIMEOUT, 0x1f402710 }, - { AR5K_XRCHIRP, 0x01f40000 }, - { AR5K_XRSTOMP, 0x00001e1c }, - { AR5K_SLEEP0, 0x0002aaaa }, - { AR5K_SLEEP1, 0x02005555 }, - { AR5K_SLEEP2, 0x00000000 }, - { AR_BSSMSKL, 0xffffffff }, - { AR_BSSMSKU, 0x0000ffff }, - { AR5K_TXPC, 0x00000000 }, - { AR5K_PROFCNT_TX, 0x00000000 }, - { AR5K_PROFCNT_RX, 0x00000000 }, - { AR5K_PROFCNT_RXCLR, 0x00000000 }, - { AR5K_PROFCNT_CYCLE, 0x00000000 }, - { AR5K_QUIET_CTL1, 0x00000088 }, - /* Initial rate duration table (32 entries )*/ - { AR5K_RATE_DUR(0), 0x00000000 }, - { AR5K_RATE_DUR(1), 0x0000008c }, - { AR5K_RATE_DUR(2), 0x000000e4 }, - { AR5K_RATE_DUR(3), 0x000002d5 }, - { AR5K_RATE_DUR(4), 0x00000000 }, - { AR5K_RATE_DUR(5), 0x00000000 }, - { AR5K_RATE_DUR(6), 0x000000a0 }, - { AR5K_RATE_DUR(7), 0x000001c9 }, - { AR5K_RATE_DUR(8), 0x0000002c }, - { AR5K_RATE_DUR(9), 0x0000002c }, - { AR5K_RATE_DUR(10), 0x00000030 }, - { AR5K_RATE_DUR(11), 0x0000003c }, - { AR5K_RATE_DUR(12), 0x0000002c }, - { AR5K_RATE_DUR(13), 0x0000002c }, - { AR5K_RATE_DUR(14), 0x00000030 }, - { AR5K_RATE_DUR(15), 0x0000003c }, - { AR5K_RATE_DUR(16), 0x00000000 }, - { AR5K_RATE_DUR(17), 0x00000000 }, - { AR5K_RATE_DUR(18), 0x00000000 }, - { AR5K_RATE_DUR(19), 0x00000000 }, - { AR5K_RATE_DUR(20), 0x00000000 }, - { AR5K_RATE_DUR(21), 0x00000000 }, - { AR5K_RATE_DUR(22), 0x00000000 }, - { AR5K_RATE_DUR(23), 0x00000000 }, - { AR5K_RATE_DUR(24), 0x000000d5 }, - { AR5K_RATE_DUR(25), 0x000000df }, - { AR5K_RATE_DUR(26), 0x00000102 }, - { AR5K_RATE_DUR(27), 0x0000013a }, - { AR5K_RATE_DUR(28), 0x00000075 }, - { AR5K_RATE_DUR(29), 0x0000007f }, - { AR5K_RATE_DUR(30), 0x000000a2 }, - { AR5K_RATE_DUR(31), 0x00000000 }, - { AR5K_QUIET_CTL2, 0x00010002 }, - { AR5K_TSF_PARM, 0x00000001 }, - { AR5K_QOS_NOACK, 0x000000c0 }, - { AR5K_PHY_ERR_FIL, 0x00000000 }, - { AR5K_XRLAT_TX, 0x00000168 }, - { AR5K_ACKSIFS, 0x00000000 }, - /* Rate -> db table - * notice ...03<-02<-01<-00 ! */ - { AR5K_RATE2DB(0), 0x03020100 }, - { AR5K_RATE2DB(1), 0x07060504 }, - { AR5K_RATE2DB(2), 0x0b0a0908 }, - { AR5K_RATE2DB(3), 0x0f0e0d0c }, - { AR5K_RATE2DB(4), 0x13121110 }, - { AR5K_RATE2DB(5), 0x17161514 }, - { AR5K_RATE2DB(6), 0x1b1a1918 }, - { AR5K_RATE2DB(7), 0x1f1e1d1c }, - /* Db -> Rate table */ - { AR5K_DB2RATE(0), 0x03020100 }, - { AR5K_DB2RATE(1), 0x07060504 }, - { AR5K_DB2RATE(2), 0x0b0a0908 }, - { AR5K_DB2RATE(3), 0x0f0e0d0c }, - { AR5K_DB2RATE(4), 0x13121110 }, - { AR5K_DB2RATE(5), 0x17161514 }, - { AR5K_DB2RATE(6), 0x1b1a1918 }, - { AR5K_DB2RATE(7), 0x1f1e1d1c }, - /* PHY registers (Common settings - * for all chips/modes) */ - { AR5K_PHY(3), 0xad848e19 }, - { AR5K_PHY(4), 0x7d28e000 }, - { AR5K_PHY_TIMING_3, 0x9c0a9f6b }, - { AR5K_PHY_ACT, 0x00000000 }, - { AR5K_PHY(16), 0x206a017a }, - { AR5K_PHY(21), 0x00000859 }, - { AR5K_PHY_BIN_MASK_1, 0x00000000 }, - { AR5K_PHY_BIN_MASK_2, 0x00000000 }, - { AR5K_PHY_BIN_MASK_3, 0x00000000 }, - { AR5K_PHY_BIN_MASK_CTL, 0x00800000 }, - { AR5K_PHY_ANT_CTL, 0x00000001 }, - /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */ - { AR5K_PHY_MAX_RX_LEN, 0x00000c80 }, - { AR5K_PHY_IQ, 0x05100000 }, - { AR5K_PHY_WARM_RESET, 0x00000001 }, - { AR5K_PHY_CTL, 0x00000004 }, - { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 }, - { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d }, - { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f }, - { AR5K_PHY(82), 0x9280b212 }, - { AR5K_PHY_RADAR, 0x5d50e188 }, - /*{ AR5K_PHY(86), 0x000000ff },*/ - { AR5K_PHY(87), 0x004b6a8e }, - { AR5K_PHY_NFTHRES, 0x000003ce }, - { AR5K_PHY_RESTART, 0x192fb515 }, - { AR5K_PHY(94), 0x00000001 }, - { AR5K_PHY_RFBUS_REQ, 0x00000000 }, - /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */ - /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */ - { AR5K_PHY(644), 0x00806333 }, - { AR5K_PHY(645), 0x00106c10 }, - { AR5K_PHY(646), 0x009c4060 }, - /* { AR5K_PHY(647), 0x1483800a }, */ - /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */ - { AR5K_PHY(648), 0x018830c6 }, - { AR5K_PHY(649), 0x00000400 }, - /*{ AR5K_PHY(650), 0x000001b5 },*/ - { AR5K_PHY(651), 0x00000000 }, - { AR5K_PHY_TXPOWER_RATE3, 0x20202020 }, - { AR5K_PHY_TXPOWER_RATE4, 0x20202020 }, - /*{ AR5K_PHY(655), 0x13c889af },*/ - { AR5K_PHY(656), 0x38490a20 }, - { AR5K_PHY(657), 0x00007bb6 }, - { AR5K_PHY(658), 0x0fff3ffc }, -}; - -/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */ -static const struct ath5k_ini_mode ar5212_ini_mode_start[] = { - { AR5K_QUEUE_DFS_LOCAL_IFS(0), - /* A/XR B G */ - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(1), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(2), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(3), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(4), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(5), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(6), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(7), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(8), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_QUEUE_DFS_LOCAL_IFS(9), - { 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } }, - { AR5K_DCU_GBL_IFS_SIFS, - { 0x00000230, 0x000000b0, 0x00000160 } }, - { AR5K_DCU_GBL_IFS_SLOT, - { 0x00000168, 0x000001b8, 0x0000018c } }, - { AR5K_DCU_GBL_IFS_EIFS, - { 0x00000e60, 0x00001f1c, 0x00003e38 } }, - { AR5K_DCU_GBL_IFS_MISC, - { 0x0000a0e0, 0x00005880, 0x0000b0e0 } }, - { AR5K_TIME_OUT, - { 0x03e803e8, 0x04200420, 0x08400840 } }, - { AR5K_PHY(8), - { 0x02020200, 0x02010200, 0x02020200 } }, - { AR5K_PHY_RF_CTL2, - { 0x00000e0e, 0x00000707, 0x00000e0e } }, - { AR5K_PHY_SETTLING, - { 0x1372161c, 0x13721722, 0x137216a2 } }, - { AR5K_PHY_AGCCTL, - { 0x00009d10, 0x00009d18, 0x00009d18 } }, - { AR5K_PHY_NF, - { 0x0001ce00, 0x0001ce00, 0x0001ce00 } }, - { AR5K_PHY_WEAK_OFDM_HIGH_THR, - { 0x409a4190, 0x409a4190, 0x409a4190 } }, - { AR5K_PHY(70), - { 0x000001b8, 0x00000084, 0x00000108 } }, - { AR5K_PHY_OFDM_SELFCORR, - { 0x10058a05, 0x10058a05, 0x10058a05 } }, - { 0xa230, - { 0x00000000, 0x00000000, 0x00000108 } }, -}; - -/* Initial mode-specific settings for AR5212 + RF5111 - * (Written after ar5212_ini) */ -static const struct ath5k_ini_mode rf5111_ini_mode_end[] = { - { AR5K_TXCFG, - /* A/XR B G */ - { 0x00008015, 0x00008015, 0x00008015 } }, - { AR5K_USEC_5211, - { 0x128d8fa7, 0x04e00f95, 0x12e00fab } }, - { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x05010100, 0x0a020001 } }, - { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, - { AR5K_PHY_PA_CTL, - { 0x00000007, 0x0000000b, 0x0000000b } }, - { AR5K_PHY_GAIN, - { 0x0018da5a, 0x0018ca69, 0x0018ca69 } }, - { AR5K_PHY_DESIRED_SIZE, - { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, - { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e } }, - { AR5K_PHY_AGCCOARSE, - { 0x3137665e, 0x3137665e, 0x3137665e } }, - { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb080 } }, - { AR5K_PHY_RX_DELAY, - { 0x00002710, 0x0000157c, 0x00002af8 } }, - { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81020, 0xf7b80d20, 0xf7b81020 } }, - { AR5K_PHY_GAIN_2GHZ, - { 0x642c416a, 0x6440416a, 0x6440416a } }, - { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1873800a, 0x1883800a } }, -}; - -/* Common for all modes */ -static const struct ath5k_ini rf5111_ini_common_end[] = { - { AR5K_DCU_FP, 0x00000000 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY_ADC_CTL, 0x00022ffe }, - { 0x983c, 0x00020100 }, - { AR5K_PHY_GAIN_OFFSET, 0x1284613c }, - { AR5K_PHY_PAPD_PROBE, 0x00004883 }, - { 0x9940, 0x00000004 }, - { 0x9958, 0x000000ff }, - { 0x9974, 0x00000000 }, - { AR5K_PHY_SPENDING, 0x00000018 }, - { AR5K_PHY_CCKTXCTL, 0x00000000 }, - { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 }, - { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 }, - { 0xa23c, 0x13c889af }, -}; - - -/* Initial mode-specific settings for AR5212 + RF5112 - * (Written after ar5212_ini) */ -static const struct ath5k_ini_mode rf5112_ini_mode_end[] = { - { AR5K_TXCFG, - /* A/XR B G */ - { 0x00008015, 0x00008015, 0x00008015 } }, - { AR5K_USEC_5211, - { 0x128d93a7, 0x04e01395, 0x12e013ab } }, - { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x05020100, 0x0a020001 } }, - { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, - { AR5K_PHY_PA_CTL, - { 0x00000007, 0x0000000b, 0x0000000b } }, - { AR5K_PHY_GAIN, - { 0x0018da6d, 0x0018ca75, 0x0018ca75 } }, - { AR5K_PHY_DESIRED_SIZE, - { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } }, - { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e } }, - { AR5K_PHY_AGCCOARSE, - { 0x3137665e, 0x3137665e, 0x3137665e } }, - { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081 } }, - { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x0000044c, 0x00000898 } }, - { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81020, 0xf7b80d10, 0xf7b81010 } }, - { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000008, 0x00000008 } }, - { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, - { AR5K_PHY_GAIN_2GHZ, - { 0x642c0140, 0x6442c160, 0x6442c160 } }, - { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1873800a, 0x1883800a } }, -}; - -static const struct ath5k_ini rf5112_ini_common_end[] = { - { AR5K_DCU_FP, 0x00000000 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY_ADC_CTL, 0x00022ffe }, - { 0x983c, 0x00020100 }, - { AR5K_PHY_GAIN_OFFSET, 0x1284613c }, - { AR5K_PHY_PAPD_PROBE, 0x00004882 }, - { 0x9940, 0x00000004 }, - { 0x9958, 0x000000ff }, - { 0x9974, 0x00000000 }, - { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 }, - { 0xa23c, 0x13c889af }, -}; - - -/* Initial mode-specific settings for RF5413/5414 - * (Written after ar5212_ini) */ -static const struct ath5k_ini_mode rf5413_ini_mode_end[] = { - { AR5K_TXCFG, - /* A/XR B G */ - { 0x00000015, 0x00000015, 0x00000015 } }, - { AR5K_USEC_5211, - { 0x128d93a7, 0x04e01395, 0x12e013ab } }, - { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x05020100, 0x0a020001 } }, - { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, - { AR5K_PHY_PA_CTL, - { 0x00000007, 0x0000000b, 0x0000000b } }, - { AR5K_PHY_GAIN, - { 0x0018fa61, 0x001a1a63, 0x001a1a63 } }, - { AR5K_PHY_DESIRED_SIZE, - { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } }, - { AR5K_PHY_SIG, - { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, - { AR5K_PHY_AGCCOARSE, - { 0x3139605e, 0x3139605e, 0x3139605e } }, - { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081 } }, - { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x0000044c, 0x00000898 } }, - { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } }, - { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000000 } }, - { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, - { AR5K_PHY_GAIN_2GHZ, - { 0x002ec1e0, 0x002ac120, 0x002ac120 } }, - { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1863800a, 0x1883800a } }, - { 0xa300, - { 0x18010000, 0x18010000, 0x18010000 } }, - { 0xa304, - { 0x30032602, 0x30032602, 0x30032602 } }, - { 0xa308, - { 0x48073e06, 0x48073e06, 0x48073e06 } }, - { 0xa30c, - { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } }, - { 0xa310, - { 0x641a600f, 0x641a600f, 0x641a600f } }, - { 0xa314, - { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } }, - { 0xa318, - { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } }, - { 0xa31c, - { 0x90cf865b, 0x8ecf865b, 0x8ecf865b } }, - { 0xa320, - { 0x9d4f970f, 0x9b4f970f, 0x9b4f970f } }, - { 0xa324, - { 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f } }, - { 0xa328, - { 0xb55faf1f, 0xb35faf1f, 0xb35faf1f } }, - { 0xa32c, - { 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f } }, - { 0xa330, - { 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f } }, - { 0xa334, - { 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } }, -}; - -static const struct ath5k_ini rf5413_ini_common_end[] = { - { AR5K_DCU_FP, 0x000003e0 }, - { AR5K_5414_CBCFG, 0x00000010 }, - { AR5K_SEQ_MASK, 0x0000000f }, - { 0x809c, 0x00000000 }, - { 0x80a0, 0x00000000 }, - { AR5K_MIC_QOS_CTL, 0x00000000 }, - { AR5K_MIC_QOS_SEL, 0x00000000 }, - { AR5K_MISC_MODE, 0x00000000 }, - { AR5K_OFDM_FIL_CNT, 0x00000000 }, - { AR5K_CCK_FIL_CNT, 0x00000000 }, - { AR5K_PHYERR_CNT1, 0x00000000 }, - { AR5K_PHYERR_CNT1_MASK, 0x00000000 }, - { AR5K_PHYERR_CNT2, 0x00000000 }, - { AR5K_PHYERR_CNT2_MASK, 0x00000000 }, - { AR5K_TSF_THRES, 0x00000000 }, - { 0x8140, 0x800003f9 }, - { 0x8144, 0x00000000 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY_ADC_CTL, 0x0000a000 }, - { 0x983c, 0x00200400 }, - { AR5K_PHY_GAIN_OFFSET, 0x1284233c }, - { AR5K_PHY_SCR, 0x0000001f }, - { AR5K_PHY_SLMT, 0x00000080 }, - { AR5K_PHY_SCAL, 0x0000000e }, - { 0x9958, 0x00081fff }, - { AR5K_PHY_TIMING_7, 0x00000000 }, - { AR5K_PHY_TIMING_8, 0x02800000 }, - { AR5K_PHY_TIMING_11, 0x00000000 }, - { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 }, - { 0x99e4, 0xaaaaaaaa }, - { 0x99e8, 0x3c466478 }, - { 0x99ec, 0x000000aa }, - { AR5K_PHY_SCLOCK, 0x0000000c }, - { AR5K_PHY_SDELAY, 0x000000ff }, - { AR5K_PHY_SPENDING, 0x00000014 }, - { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 }, - { 0xa23c, 0x93c889af }, - { AR5K_PHY_FAST_ADC, 0x00000001 }, - { 0xa250, 0x0000a000 }, - { AR5K_PHY_BLUETOOTH, 0x00000000 }, - { AR5K_PHY_TPC_RG1, 0x0cc75380 }, - { 0xa25c, 0x0f0f0f01 }, - { 0xa260, 0x5f690f01 }, - { 0xa264, 0x00418a11 }, - { 0xa268, 0x00000000 }, - { AR5K_PHY_TPC_RG5, 0x0c30c16a }, - { 0xa270, 0x00820820 }, - { 0xa274, 0x081b7caa }, - { 0xa278, 0x1ce739ce }, - { 0xa27c, 0x051701ce }, - { 0xa338, 0x00000000 }, - { 0xa33c, 0x00000000 }, - { 0xa340, 0x00000000 }, - { 0xa344, 0x00000000 }, - { 0xa348, 0x3fffffff }, - { 0xa34c, 0x3fffffff }, - { 0xa350, 0x3fffffff }, - { 0xa354, 0x0003ffff }, - { 0xa358, 0x79a8aa1f }, - { 0xa35c, 0x066c420f }, - { 0xa360, 0x0f282207 }, - { 0xa364, 0x17601685 }, - { 0xa368, 0x1f801104 }, - { 0xa36c, 0x37a00c03 }, - { 0xa370, 0x3fc40883 }, - { 0xa374, 0x57c00803 }, - { 0xa378, 0x5fd80682 }, - { 0xa37c, 0x7fe00482 }, - { 0xa380, 0x7f3c7bba }, - { 0xa384, 0xf3307ff0 }, -}; - -/* Initial mode-specific settings for RF2413/2414 - * (Written after ar5212_ini) */ -/* XXX: a mode ? */ -static const struct ath5k_ini_mode rf2413_ini_mode_end[] = { - { AR5K_TXCFG, - /* A/XR B G */ - { 0x00000015, 0x00000015, 0x00000015 } }, - { AR5K_USEC_5211, - { 0x128d93a7, 0x04e01395, 0x12e013ab } }, - { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x05020000, 0x0a020001 } }, - { AR5K_PHY_RF_CTL4, - { 0x00000e00, 0x00000e00, 0x00000e00 } }, - { AR5K_PHY_PA_CTL, - { 0x00000002, 0x0000000a, 0x0000000a } }, - { AR5K_PHY_GAIN, - { 0x0018da6d, 0x001a6a64, 0x001a6a64 } }, - { AR5K_PHY_DESIRED_SIZE, - { 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da } }, - { AR5K_PHY_SIG, - { 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e } }, - { AR5K_PHY_AGCCOARSE, - { 0x3137665e, 0x3137665e, 0x3139605e } }, - { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081 } }, - { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x0000044c, 0x00000898 } }, - { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } }, - { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000000 } }, - { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, - { AR5K_PHY_GAIN_2GHZ, - { 0x002c0140, 0x0042c140, 0x0042c140 } }, - { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1863800a, 0x1883800a } }, -}; - -static const struct ath5k_ini rf2413_ini_common_end[] = { - { AR5K_DCU_FP, 0x000003e0 }, - { AR5K_SEQ_MASK, 0x0000000f }, - { AR5K_MIC_QOS_CTL, 0x00000000 }, - { AR5K_MIC_QOS_SEL, 0x00000000 }, - { AR5K_MISC_MODE, 0x00000000 }, - { AR5K_OFDM_FIL_CNT, 0x00000000 }, - { AR5K_CCK_FIL_CNT, 0x00000000 }, - { AR5K_PHYERR_CNT1, 0x00000000 }, - { AR5K_PHYERR_CNT1_MASK, 0x00000000 }, - { AR5K_PHYERR_CNT2, 0x00000000 }, - { AR5K_PHYERR_CNT2_MASK, 0x00000000 }, - { AR5K_TSF_THRES, 0x00000000 }, - { 0x8140, 0x800000a8 }, - { 0x8144, 0x00000000 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY_ADC_CTL, 0x0000a000 }, - { 0x983c, 0x00200400 }, - { AR5K_PHY_GAIN_OFFSET, 0x1284233c }, - { AR5K_PHY_SCR, 0x0000001f }, - { AR5K_PHY_SLMT, 0x00000080 }, - { AR5K_PHY_SCAL, 0x0000000e }, - { 0x9958, 0x000000ff }, - { AR5K_PHY_TIMING_7, 0x00000000 }, - { AR5K_PHY_TIMING_8, 0x02800000 }, - { AR5K_PHY_TIMING_11, 0x00000000 }, - { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 }, - { 0x99e4, 0xaaaaaaaa }, - { 0x99e8, 0x3c466478 }, - { 0x99ec, 0x000000aa }, - { AR5K_PHY_SCLOCK, 0x0000000c }, - { AR5K_PHY_SDELAY, 0x000000ff }, - { AR5K_PHY_SPENDING, 0x00000014 }, - { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 }, - { 0xa23c, 0x93c889af }, - { AR5K_PHY_FAST_ADC, 0x00000001 }, - { 0xa250, 0x0000a000 }, - { AR5K_PHY_BLUETOOTH, 0x00000000 }, - { AR5K_PHY_TPC_RG1, 0x0cc75380 }, - { 0xa25c, 0x0f0f0f01 }, - { 0xa260, 0x5f690f01 }, - { 0xa264, 0x00418a11 }, - { 0xa268, 0x00000000 }, - { AR5K_PHY_TPC_RG5, 0x0c30c16a }, - { 0xa270, 0x00820820 }, - { 0xa274, 0x001b7caa }, - { 0xa278, 0x1ce739ce }, - { 0xa27c, 0x051701ce }, - { 0xa300, 0x18010000 }, - { 0xa304, 0x30032602 }, - { 0xa308, 0x48073e06 }, - { 0xa30c, 0x560b4c0a }, - { 0xa310, 0x641a600f }, - { 0xa314, 0x784f6e1b }, - { 0xa318, 0x868f7c5a }, - { 0xa31c, 0x8ecf865b }, - { 0xa320, 0x9d4f970f }, - { 0xa324, 0xa5cfa18f }, - { 0xa328, 0xb55faf1f }, - { 0xa32c, 0xbddfb99f }, - { 0xa330, 0xcd7fc73f }, - { 0xa334, 0xd5ffd1bf }, - { 0xa338, 0x00000000 }, - { 0xa33c, 0x00000000 }, - { 0xa340, 0x00000000 }, - { 0xa344, 0x00000000 }, - { 0xa348, 0x3fffffff }, - { 0xa34c, 0x3fffffff }, - { 0xa350, 0x3fffffff }, - { 0xa354, 0x0003ffff }, - { 0xa358, 0x79a8aa1f }, - { 0xa35c, 0x066c420f }, - { 0xa360, 0x0f282207 }, - { 0xa364, 0x17601685 }, - { 0xa368, 0x1f801104 }, - { 0xa36c, 0x37a00c03 }, - { 0xa370, 0x3fc40883 }, - { 0xa374, 0x57c00803 }, - { 0xa378, 0x5fd80682 }, - { 0xa37c, 0x7fe00482 }, - { 0xa380, 0x7f3c7bba }, - { 0xa384, 0xf3307ff0 }, -}; - -/* Initial mode-specific settings for RF2425 - * (Written after ar5212_ini) */ -/* XXX: a mode ? */ -static const struct ath5k_ini_mode rf2425_ini_mode_end[] = { - { AR5K_TXCFG, - /* A/XR B G */ - { 0x00000015, 0x00000015, 0x00000015 } }, - { AR5K_USEC_5211, - { 0x128d93a7, 0x04e01395, 0x12e013ab } }, - { AR5K_PHY_RF_CTL3, - { 0x0a020001, 0x05020100, 0x0a020001 } }, - { AR5K_PHY_RF_CTL4, - { 0x00000e0e, 0x00000e0e, 0x00000e0e } }, - { AR5K_PHY_PA_CTL, - { 0x00000003, 0x0000000b, 0x0000000b } }, - { AR5K_PHY_SETTLING, - { 0x1372161c, 0x13721722, 0x13721422 } }, - { AR5K_PHY_GAIN, - { 0x0018fa61, 0x00199a65, 0x00199a65 } }, - { AR5K_PHY_DESIRED_SIZE, - { 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da } }, - { AR5K_PHY_SIG, - { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } }, - { AR5K_PHY_AGCCOARSE, - { 0x3139605e, 0x3139605e, 0x3139605e } }, - { AR5K_PHY_WEAK_OFDM_LOW_THR, - { 0x050cb081, 0x050cb081, 0x050cb081 } }, - { AR5K_PHY_RX_DELAY, - { 0x000007d0, 0x0000044c, 0x00000898 } }, - { AR5K_PHY_FRAME_CTL_5211, - { 0xf7b81000, 0xf7b80d00, 0xf7b81000 } }, - { AR5K_PHY_CCKTXCTL, - { 0x00000000, 0x00000000, 0x00000000 } }, - { AR5K_PHY_CCK_CROSSCORR, - { 0xd6be6788, 0xd03e6788, 0xd03e6788 } }, - { AR5K_PHY_GAIN_2GHZ, - { 0x00000140, 0x0052c140, 0x0052c140 } }, - { AR5K_PHY_CCK_RX_CTL_4, - { 0x1883800a, 0x1863800a, 0x1883800a } }, - { 0xa324, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, - { 0xa328, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, - { 0xa32c, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, - { 0xa330, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, - { 0xa334, - { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } }, -}; - -static const struct ath5k_ini rf2425_ini_common_end[] = { - { AR5K_DCU_FP, 0x000003e0 }, - { AR5K_SEQ_MASK, 0x0000000f }, - { 0x809c, 0x00000000 }, - { 0x80a0, 0x00000000 }, - { AR5K_MIC_QOS_CTL, 0x00000000 }, - { AR5K_MIC_QOS_SEL, 0x00000000 }, - { AR5K_MISC_MODE, 0x00000000 }, - { AR5K_OFDM_FIL_CNT, 0x00000000 }, - { AR5K_CCK_FIL_CNT, 0x00000000 }, - { AR5K_PHYERR_CNT1, 0x00000000 }, - { AR5K_PHYERR_CNT1_MASK, 0x00000000 }, - { AR5K_PHYERR_CNT2, 0x00000000 }, - { AR5K_PHYERR_CNT2_MASK, 0x00000000 }, - { AR5K_TSF_THRES, 0x00000000 }, - { 0x8140, 0x800003f9 }, - { 0x8144, 0x00000000 }, - { AR5K_PHY_AGC, 0x00000000 }, - { AR5K_PHY_ADC_CTL, 0x0000a000 }, - { 0x983c, 0x00200400 }, - { AR5K_PHY_GAIN_OFFSET, 0x1284233c }, - { AR5K_PHY_SCR, 0x0000001f }, - { AR5K_PHY_SLMT, 0x00000080 }, - { AR5K_PHY_SCAL, 0x0000000e }, - { 0x9958, 0x00081fff }, - { AR5K_PHY_TIMING_7, 0x00000000 }, - { AR5K_PHY_TIMING_8, 0x02800000 }, - { AR5K_PHY_TIMING_11, 0x00000000 }, - { 0x99dc, 0xfebadbe8 }, - { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 }, - { 0x99e4, 0xaaaaaaaa }, - { 0x99e8, 0x3c466478 }, - { 0x99ec, 0x000000aa }, - { AR5K_PHY_SCLOCK, 0x0000000c }, - { AR5K_PHY_SDELAY, 0x000000ff }, - { AR5K_PHY_SPENDING, 0x00000014 }, - { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 }, - { AR5K_PHY_TXPOWER_RATE3, 0x20202020 }, - { AR5K_PHY_TXPOWER_RATE4, 0x20202020 }, - { 0xa23c, 0x93c889af }, - { AR5K_PHY_FAST_ADC, 0x00000001 }, - { 0xa250, 0x0000a000 }, - { AR5K_PHY_BLUETOOTH, 0x00000000 }, - { AR5K_PHY_TPC_RG1, 0x0cc75380 }, - { 0xa25c, 0x0f0f0f01 }, - { 0xa260, 0x5f690f01 }, - { 0xa264, 0x00418a11 }, - { 0xa268, 0x00000000 }, - { AR5K_PHY_TPC_RG5, 0x0c30c166 }, - { 0xa270, 0x00820820 }, - { 0xa274, 0x081a3caa }, - { 0xa278, 0x1ce739ce }, - { 0xa27c, 0x051701ce }, - { 0xa300, 0x16010000 }, - { 0xa304, 0x2c032402 }, - { 0xa308, 0x48433e42 }, - { 0xa30c, 0x5a0f500b }, - { 0xa310, 0x6c4b624a }, - { 0xa314, 0x7e8b748a }, - { 0xa318, 0x96cf8ccb }, - { 0xa31c, 0xa34f9d0f }, - { 0xa320, 0xa7cfa58f }, - { 0xa348, 0x3fffffff }, - { 0xa34c, 0x3fffffff }, - { 0xa350, 0x3fffffff }, - { 0xa354, 0x0003ffff }, - { 0xa358, 0x79a8aa1f }, - { 0xa35c, 0x066c420f }, - { 0xa360, 0x0f282207 }, - { 0xa364, 0x17601685 }, - { 0xa368, 0x1f801104 }, - { 0xa36c, 0x37a00c03 }, - { 0xa370, 0x3fc40883 }, - { 0xa374, 0x57c00803 }, - { 0xa378, 0x5fd80682 }, - { 0xa37c, 0x7fe00482 }, - { 0xa380, 0x7f3c7bba }, - { 0xa384, 0xf3307ff0 }, -}; - -/* - * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with - * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI) - */ - -/* RF5111 Initial BaseBand Gain settings */ -static const struct ath5k_ini rf5111_ini_bbgain[] = { - { AR5K_BB_GAIN(0), 0x00000000 }, - { AR5K_BB_GAIN(1), 0x00000020 }, - { AR5K_BB_GAIN(2), 0x00000010 }, - { AR5K_BB_GAIN(3), 0x00000030 }, - { AR5K_BB_GAIN(4), 0x00000008 }, - { AR5K_BB_GAIN(5), 0x00000028 }, - { AR5K_BB_GAIN(6), 0x00000004 }, - { AR5K_BB_GAIN(7), 0x00000024 }, - { AR5K_BB_GAIN(8), 0x00000014 }, - { AR5K_BB_GAIN(9), 0x00000034 }, - { AR5K_BB_GAIN(10), 0x0000000c }, - { AR5K_BB_GAIN(11), 0x0000002c }, - { AR5K_BB_GAIN(12), 0x00000002 }, - { AR5K_BB_GAIN(13), 0x00000022 }, - { AR5K_BB_GAIN(14), 0x00000012 }, - { AR5K_BB_GAIN(15), 0x00000032 }, - { AR5K_BB_GAIN(16), 0x0000000a }, - { AR5K_BB_GAIN(17), 0x0000002a }, - { AR5K_BB_GAIN(18), 0x00000006 }, - { AR5K_BB_GAIN(19), 0x00000026 }, - { AR5K_BB_GAIN(20), 0x00000016 }, - { AR5K_BB_GAIN(21), 0x00000036 }, - { AR5K_BB_GAIN(22), 0x0000000e }, - { AR5K_BB_GAIN(23), 0x0000002e }, - { AR5K_BB_GAIN(24), 0x00000001 }, - { AR5K_BB_GAIN(25), 0x00000021 }, - { AR5K_BB_GAIN(26), 0x00000011 }, - { AR5K_BB_GAIN(27), 0x00000031 }, - { AR5K_BB_GAIN(28), 0x00000009 }, - { AR5K_BB_GAIN(29), 0x00000029 }, - { AR5K_BB_GAIN(30), 0x00000005 }, - { AR5K_BB_GAIN(31), 0x00000025 }, - { AR5K_BB_GAIN(32), 0x00000015 }, - { AR5K_BB_GAIN(33), 0x00000035 }, - { AR5K_BB_GAIN(34), 0x0000000d }, - { AR5K_BB_GAIN(35), 0x0000002d }, - { AR5K_BB_GAIN(36), 0x00000003 }, - { AR5K_BB_GAIN(37), 0x00000023 }, - { AR5K_BB_GAIN(38), 0x00000013 }, - { AR5K_BB_GAIN(39), 0x00000033 }, - { AR5K_BB_GAIN(40), 0x0000000b }, - { AR5K_BB_GAIN(41), 0x0000002b }, - { AR5K_BB_GAIN(42), 0x0000002b }, - { AR5K_BB_GAIN(43), 0x0000002b }, - { AR5K_BB_GAIN(44), 0x0000002b }, - { AR5K_BB_GAIN(45), 0x0000002b }, - { AR5K_BB_GAIN(46), 0x0000002b }, - { AR5K_BB_GAIN(47), 0x0000002b }, - { AR5K_BB_GAIN(48), 0x0000002b }, - { AR5K_BB_GAIN(49), 0x0000002b }, - { AR5K_BB_GAIN(50), 0x0000002b }, - { AR5K_BB_GAIN(51), 0x0000002b }, - { AR5K_BB_GAIN(52), 0x0000002b }, - { AR5K_BB_GAIN(53), 0x0000002b }, - { AR5K_BB_GAIN(54), 0x0000002b }, - { AR5K_BB_GAIN(55), 0x0000002b }, - { AR5K_BB_GAIN(56), 0x0000002b }, - { AR5K_BB_GAIN(57), 0x0000002b }, - { AR5K_BB_GAIN(58), 0x0000002b }, - { AR5K_BB_GAIN(59), 0x0000002b }, - { AR5K_BB_GAIN(60), 0x0000002b }, - { AR5K_BB_GAIN(61), 0x0000002b }, - { AR5K_BB_GAIN(62), 0x00000002 }, - { AR5K_BB_GAIN(63), 0x00000016 }, -}; - -/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */ -static const struct ath5k_ini rf5112_ini_bbgain[] = { - { AR5K_BB_GAIN(0), 0x00000000 }, - { AR5K_BB_GAIN(1), 0x00000001 }, - { AR5K_BB_GAIN(2), 0x00000002 }, - { AR5K_BB_GAIN(3), 0x00000003 }, - { AR5K_BB_GAIN(4), 0x00000004 }, - { AR5K_BB_GAIN(5), 0x00000005 }, - { AR5K_BB_GAIN(6), 0x00000008 }, - { AR5K_BB_GAIN(7), 0x00000009 }, - { AR5K_BB_GAIN(8), 0x0000000a }, - { AR5K_BB_GAIN(9), 0x0000000b }, - { AR5K_BB_GAIN(10), 0x0000000c }, - { AR5K_BB_GAIN(11), 0x0000000d }, - { AR5K_BB_GAIN(12), 0x00000010 }, - { AR5K_BB_GAIN(13), 0x00000011 }, - { AR5K_BB_GAIN(14), 0x00000012 }, - { AR5K_BB_GAIN(15), 0x00000013 }, - { AR5K_BB_GAIN(16), 0x00000014 }, - { AR5K_BB_GAIN(17), 0x00000015 }, - { AR5K_BB_GAIN(18), 0x00000018 }, - { AR5K_BB_GAIN(19), 0x00000019 }, - { AR5K_BB_GAIN(20), 0x0000001a }, - { AR5K_BB_GAIN(21), 0x0000001b }, - { AR5K_BB_GAIN(22), 0x0000001c }, - { AR5K_BB_GAIN(23), 0x0000001d }, - { AR5K_BB_GAIN(24), 0x00000020 }, - { AR5K_BB_GAIN(25), 0x00000021 }, - { AR5K_BB_GAIN(26), 0x00000022 }, - { AR5K_BB_GAIN(27), 0x00000023 }, - { AR5K_BB_GAIN(28), 0x00000024 }, - { AR5K_BB_GAIN(29), 0x00000025 }, - { AR5K_BB_GAIN(30), 0x00000028 }, - { AR5K_BB_GAIN(31), 0x00000029 }, - { AR5K_BB_GAIN(32), 0x0000002a }, - { AR5K_BB_GAIN(33), 0x0000002b }, - { AR5K_BB_GAIN(34), 0x0000002c }, - { AR5K_BB_GAIN(35), 0x0000002d }, - { AR5K_BB_GAIN(36), 0x00000030 }, - { AR5K_BB_GAIN(37), 0x00000031 }, - { AR5K_BB_GAIN(38), 0x00000032 }, - { AR5K_BB_GAIN(39), 0x00000033 }, - { AR5K_BB_GAIN(40), 0x00000034 }, - { AR5K_BB_GAIN(41), 0x00000035 }, - { AR5K_BB_GAIN(42), 0x00000035 }, - { AR5K_BB_GAIN(43), 0x00000035 }, - { AR5K_BB_GAIN(44), 0x00000035 }, - { AR5K_BB_GAIN(45), 0x00000035 }, - { AR5K_BB_GAIN(46), 0x00000035 }, - { AR5K_BB_GAIN(47), 0x00000035 }, - { AR5K_BB_GAIN(48), 0x00000035 }, - { AR5K_BB_GAIN(49), 0x00000035 }, - { AR5K_BB_GAIN(50), 0x00000035 }, - { AR5K_BB_GAIN(51), 0x00000035 }, - { AR5K_BB_GAIN(52), 0x00000035 }, - { AR5K_BB_GAIN(53), 0x00000035 }, - { AR5K_BB_GAIN(54), 0x00000035 }, - { AR5K_BB_GAIN(55), 0x00000035 }, - { AR5K_BB_GAIN(56), 0x00000035 }, - { AR5K_BB_GAIN(57), 0x00000035 }, - { AR5K_BB_GAIN(58), 0x00000035 }, - { AR5K_BB_GAIN(59), 0x00000035 }, - { AR5K_BB_GAIN(60), 0x00000035 }, - { AR5K_BB_GAIN(61), 0x00000035 }, - { AR5K_BB_GAIN(62), 0x00000010 }, - { AR5K_BB_GAIN(63), 0x0000001a }, -}; - - -/** - * ath5k_hw_ini_registers() - Write initial register dump common for all modes - * @ah: The &struct ath5k_hw - * @size: Dump size - * @ini_regs: The array of &struct ath5k_ini - * @skip_pcu: Skip PCU registers - */ -static void -ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size, - const struct ath5k_ini *ini_regs, bool skip_pcu) -{ - unsigned int i; - - /* Write initial registers */ - for (i = 0; i < size; i++) { - /* Skip PCU registers if - * requested */ - if (skip_pcu && - ini_regs[i].ini_register >= AR5K_PCU_MIN && - ini_regs[i].ini_register <= AR5K_PCU_MAX) - continue; - - switch (ini_regs[i].ini_mode) { - case AR5K_INI_READ: - /* Cleared on read */ - ath5k_hw_reg_read(ah, ini_regs[i].ini_register); - break; - case AR5K_INI_WRITE: - default: - AR5K_REG_WAIT(i); - ath5k_hw_reg_write(ah, ini_regs[i].ini_value, - ini_regs[i].ini_register); - } - } -} - -/** - * ath5k_hw_ini_mode_registers() - Write initial mode-specific register dump - * @ah: The &struct ath5k_hw - * @size: Dump size - * @ini_mode: The array of &struct ath5k_ini_mode - * @mode: One of enum ath5k_driver_mode - */ -static void -ath5k_hw_ini_mode_registers(struct ath5k_hw *ah, - unsigned int size, const struct ath5k_ini_mode *ini_mode, - u8 mode) -{ - unsigned int i; - - for (i = 0; i < size; i++) { - AR5K_REG_WAIT(i); - ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode], - (u32)ini_mode[i].mode_register); - } - -} - -/** - * ath5k_hw_write_initvals() - Write initial chip-specific register dump - * @ah: The &struct ath5k_hw - * @mode: One of enum ath5k_driver_mode - * @skip_pcu: Skip PCU registers - * - * Write initial chip-specific register dump, to get the chipset on a - * clean and ready-to-work state after warm reset. - */ -int -ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool skip_pcu) -{ - /* - * Write initial register settings - */ - - /* For AR5212 and compatible */ - if (ah->ah_version == AR5K_AR5212) { - - /* First set of mode-specific settings */ - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(ar5212_ini_mode_start), - ar5212_ini_mode_start, mode); - - /* - * Write initial settings common for all modes - */ - ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start), - ar5212_ini_common_start, skip_pcu); - - /* Second set of mode-specific settings */ - switch (ah->ah_radio) { - case AR5K_RF5111: - - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(rf5111_ini_mode_end), - rf5111_ini_mode_end, mode); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5111_ini_common_end), - rf5111_ini_common_end, skip_pcu); - - /* Baseband gain table */ - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5111_ini_bbgain), - rf5111_ini_bbgain, skip_pcu); - - break; - case AR5K_RF5112: - - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(rf5112_ini_mode_end), - rf5112_ini_mode_end, mode); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5112_ini_common_end), - rf5112_ini_common_end, skip_pcu); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, skip_pcu); - - break; - case AR5K_RF5413: - - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(rf5413_ini_mode_end), - rf5413_ini_mode_end, mode); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5413_ini_common_end), - rf5413_ini_common_end, skip_pcu); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, skip_pcu); - - break; - case AR5K_RF2316: - case AR5K_RF2413: - - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(rf2413_ini_mode_end), - rf2413_ini_mode_end, mode); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf2413_ini_common_end), - rf2413_ini_common_end, skip_pcu); - - /* Override settings from rf2413_ini_common_end */ - if (ah->ah_radio == AR5K_RF2316) { - ath5k_hw_reg_write(ah, 0x00004000, - AR5K_PHY_AGC); - ath5k_hw_reg_write(ah, 0x081b7caa, - 0xa274); - } - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, skip_pcu); - break; - case AR5K_RF2317: - - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(rf2413_ini_mode_end), - rf2413_ini_mode_end, mode); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf2425_ini_common_end), - rf2425_ini_common_end, skip_pcu); - - /* Override settings from rf2413_ini_mode_end */ - ath5k_hw_reg_write(ah, 0x00180a65, AR5K_PHY_GAIN); - - /* Override settings from rf2413_ini_common_end */ - ath5k_hw_reg_write(ah, 0x00004000, AR5K_PHY_AGC); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TPC_RG5, - AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP, 0xa); - ath5k_hw_reg_write(ah, 0x800000a8, 0x8140); - ath5k_hw_reg_write(ah, 0x000000ff, 0x9958); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, skip_pcu); - break; - case AR5K_RF2425: - - ath5k_hw_ini_mode_registers(ah, - ARRAY_SIZE(rf2425_ini_mode_end), - rf2425_ini_mode_end, mode); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf2425_ini_common_end), - rf2425_ini_common_end, skip_pcu); - - ath5k_hw_ini_registers(ah, - ARRAY_SIZE(rf5112_ini_bbgain), - rf5112_ini_bbgain, skip_pcu); - break; - default: - return -EINVAL; - - } - - /* For AR5211 */ - } else if (ah->ah_version == AR5K_AR5211) { - - /* AR5K_MODE_11B */ - if (mode > 2) { - ATH5K_ERR(ah, - "unsupported channel mode: %d\n", mode); - return -EINVAL; - } - - /* Mode-specific settings */ - ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode), - ar5211_ini_mode, mode); - - /* - * Write initial settings common for all modes - */ - ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini), - ar5211_ini, skip_pcu); - - /* AR5211 only comes with 5111 */ - - /* Baseband gain table */ - ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain), - rf5111_ini_bbgain, skip_pcu); - /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */ - } else if (ah->ah_version == AR5K_AR5210) { - ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini), - ar5210_ini, skip_pcu); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/led.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/led.c deleted file mode 100644 index c1151c72..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/led.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2004-2005 Atheros Communications, Inc. - * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - * - */ - -#include <linux/pci.h> -#include "ath5k.h" - -#define ATH_SDEVICE(subv, subd) \ - .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ - .subvendor = (subv), .subdevice = (subd) - -#define ATH_LED(pin, polarity) .driver_data = (((pin) << 8) | (polarity)) -#define ATH_PIN(data) ((data) >> 8) -#define ATH_POLARITY(data) ((data) & 0xff) - -/* Devices we match on for LED config info (typically laptops) */ -static DEFINE_PCI_DEVICE_TABLE(ath5k_led_devices) = { - /* AR5211 */ - { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) }, - /* HP Compaq nc6xx, nc4000, nx6000 */ - { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) }, - /* Acer Aspire One A150 (maximlevitsky@gmail.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) }, - /* Acer Aspire One AO531h AO751h (keng-yu.lin@canonical.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe00d), ATH_LED(3, 0) }, - /* Acer Ferrari 5000 (russ.dill@gmail.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) }, - /* E-machines E510 (tuliom@gmail.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) }, - /* BenQ Joybook R55v (nowymarluk@wp.pl) */ - { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) }, - /* Acer Extensa 5620z (nekoreeve@gmail.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) }, - /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */ - { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) }, - /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */ - { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) }, - /* HP Compaq CQ60-206US (ddreggors@jumptv.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, - /* HP Compaq C700 (nitrousnrg@gmail.com) */ - { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, - /* LiteOn AR5BXB63 (magooz@salug.it) */ - { ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) }, - /* IBM-specific AR5212 (all others) */ - { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, - /* Dell Vostro A860 (shahar@shahar-or.co.il) */ - { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0112), ATH_LED(3, 0) }, - { } -}; - -void ath5k_led_enable(struct ath5k_hw *ah) -{ - if (test_bit(ATH_STAT_LEDSOFT, ah->status)) { - ath5k_hw_set_gpio_output(ah, ah->led_pin); - ath5k_led_off(ah); - } -} - -static void ath5k_led_on(struct ath5k_hw *ah) -{ - if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) - return; - ath5k_hw_set_gpio(ah, ah->led_pin, ah->led_on); -} - -void ath5k_led_off(struct ath5k_hw *ah) -{ - if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) - return; - ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on); -} - -static void -ath5k_led_brightness_set(struct led_classdev *led_dev, - enum led_brightness brightness) -{ - struct ath5k_led *led = container_of(led_dev, struct ath5k_led, - led_dev); - - if (brightness == LED_OFF) - ath5k_led_off(led->ah); - else - ath5k_led_on(led->ah); -} - -static int -ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, - const char *name, char *trigger) -{ - int err; - - led->ah = ah; - strncpy(led->name, name, sizeof(led->name)); - led->led_dev.name = led->name; - led->led_dev.default_trigger = trigger; - led->led_dev.brightness_set = ath5k_led_brightness_set; - - err = led_classdev_register(ah->dev, &led->led_dev); - if (err) { - ATH5K_WARN(ah, "could not register LED %s\n", name); - led->ah = NULL; - } - return err; -} - -static void -ath5k_unregister_led(struct ath5k_led *led) -{ - if (!led->ah) - return; - led_classdev_unregister(&led->led_dev); - ath5k_led_off(led->ah); - led->ah = NULL; -} - -void ath5k_unregister_leds(struct ath5k_hw *ah) -{ - ath5k_unregister_led(&ah->rx_led); - ath5k_unregister_led(&ah->tx_led); -} - -int __devinit ath5k_init_leds(struct ath5k_hw *ah) -{ - int ret = 0; - struct ieee80211_hw *hw = ah->hw; -#ifndef CONFIG_ATHEROS_AR231X - struct pci_dev *pdev = ah->pdev; -#endif - char name[ATH5K_LED_MAX_NAME_LEN + 1]; - const struct pci_device_id *match; - - if (!ah->pdev) - return 0; - -#ifdef CONFIG_ATHEROS_AR231X - match = NULL; -#else - match = pci_match_id(&ath5k_led_devices[0], pdev); -#endif - if (match) { - __set_bit(ATH_STAT_LEDSOFT, ah->status); - ah->led_pin = ATH_PIN(match->driver_data); - ah->led_on = ATH_POLARITY(match->driver_data); - } - - if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) - goto out; - - ath5k_led_enable(ah); - - snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy)); - ret = ath5k_register_led(ah, &ah->rx_led, name, - ieee80211_get_rx_led_name(hw)); - if (ret) - goto out; - - snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy)); - ret = ath5k_register_led(ah, &ah->tx_led, name, - ieee80211_get_tx_led_name(hw)); -out: - return ret; -} - diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/mac80211-ops.c deleted file mode 100644 index 5c532995..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ /dev/null @@ -1,823 +0,0 @@ -/*- - * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting - * Copyright (c) 2004-2005 Atheros Communications, Inc. - * Copyright (c) 2006 Devicescape Software, Inc. - * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> - * Copyright (c) 2010 Bruno Randolf <br1@einfach.org> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - * - */ - -#include <net/mac80211.h> -#include <asm/unaligned.h> - -#include "ath5k.h" -#include "base.h" -#include "reg.h" - -/********************\ -* Mac80211 functions * -\********************/ - -static void -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct ath5k_hw *ah = hw->priv; - u16 qnum = skb_get_queue_mapping(skb); - - if (WARN_ON(qnum >= ah->ah_capabilities.cap_queues.q_tx_num)) { - dev_kfree_skb_any(skb); - return; - } - - ath5k_tx_queue(hw, skb, &ah->txqs[qnum]); -} - - -static int -ath5k_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct ath5k_hw *ah = hw->priv; - int ret; - struct ath5k_vif *avf = (void *)vif->drv_priv; - - mutex_lock(&ah->lock); - - if ((vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) - && (ah->num_ap_vifs + ah->num_adhoc_vifs) >= ATH_BCBUF) { - ret = -ELNRNG; - goto end; - } - - /* Don't allow other interfaces if one ad-hoc is configured. - * TODO: Fix the problems with ad-hoc and multiple other interfaces. - * We would need to operate the HW in ad-hoc mode to allow TSF updates - * for the IBSS, but this breaks with additional AP or STA interfaces - * at the moment. */ - if (ah->num_adhoc_vifs || - (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { - ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n"); - ret = -ELNRNG; - goto end; - } - - switch (vif->type) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_MESH_POINT: - avf->opmode = vif->type; - break; - default: - ret = -EOPNOTSUPP; - goto end; - } - - ah->nvifs++; - ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); - - /* Assign the vap/adhoc to a beacon xmit slot. */ - if ((avf->opmode == NL80211_IFTYPE_AP) || - (avf->opmode == NL80211_IFTYPE_ADHOC) || - (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { - int slot; - - WARN_ON(list_empty(&ah->bcbuf)); - avf->bbuf = list_first_entry(&ah->bcbuf, struct ath5k_buf, - list); - list_del(&avf->bbuf->list); - - avf->bslot = 0; - for (slot = 0; slot < ATH_BCBUF; slot++) { - if (!ah->bslot[slot]) { - avf->bslot = slot; - break; - } - } - BUG_ON(ah->bslot[avf->bslot] != NULL); - ah->bslot[avf->bslot] = vif; - if (avf->opmode == NL80211_IFTYPE_AP) - 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 - * filter. - */ - ath5k_hw_set_lladdr(ah, vif->addr); - - ath5k_update_bssid_mask_and_opmode(ah, vif); - ret = 0; -end: - mutex_unlock(&ah->lock); - return ret; -} - - -static void -ath5k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ath5k_hw *ah = hw->priv; - struct ath5k_vif *avf = (void *)vif->drv_priv; - unsigned int i; - - mutex_lock(&ah->lock); - ah->nvifs--; - - if (avf->bbuf) { - ath5k_txbuf_free_skb(ah, avf->bbuf); - list_add_tail(&avf->bbuf->list, &ah->bcbuf); - for (i = 0; i < ATH_BCBUF; i++) { - if (ah->bslot[i] == vif) { - ah->bslot[i] = NULL; - break; - } - } - avf->bbuf = NULL; - } - if (avf->opmode == NL80211_IFTYPE_AP) - 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); -} - - -/* - * TODO: Phy disable/diversity etc - */ -static int -ath5k_config(struct ieee80211_hw *hw, u32 changed) -{ - struct ath5k_hw *ah = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - int ret = 0; - int i; - - mutex_lock(&ah->lock); - - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ret = ath5k_chan_set(ah, conf->channel); - if (ret < 0) - goto unlock; - } - - if ((changed & IEEE80211_CONF_CHANGE_POWER) && - (ah->power_level != conf->power_level)) { - ah->power_level = conf->power_level; - - /* Half dB steps */ - ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); - } - - if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - ah->ah_retry_long = conf->long_frame_max_tx_count; - ah->ah_retry_short = conf->short_frame_max_tx_count; - - for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) - ath5k_hw_set_tx_retry_limits(ah, i); - } - - /* TODO: - * 1) Move this on config_interface and handle each case - * separately eg. when we have only one STA vif, use - * AR5K_ANTMODE_SINGLE_AP - * - * 2) Allow the user to change antenna mode eg. when only - * one antenna is present - * - * 3) Allow the user to set default/tx antenna when possible - * - * 4) Default mode should handle 90% of the cases, together - * with fixed a/b and single AP modes we should be able to - * handle 99%. Sectored modes are extreme cases and i still - * haven't found a usage for them. If we decide to support them, - * then we must allow the user to set how many tx antennas we - * have available - */ - ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); - -unlock: - mutex_unlock(&ah->lock); - return ret; -} - - -static void -ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, u32 changes) -{ - struct ath5k_vif *avf = (void *)vif->drv_priv; - struct ath5k_hw *ah = hw->priv; - struct ath_common *common = ath5k_hw_common(ah); - unsigned long flags; - - mutex_lock(&ah->lock); - - if (changes & BSS_CHANGED_BSSID) { - /* Cache for later use during resets */ - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - common->curaid = 0; - ath5k_hw_set_bssid(ah); - mmiowb(); - } - - if (changes & BSS_CHANGED_BEACON_INT) - ah->bintval = bss_conf->beacon_int; - - if (changes & BSS_CHANGED_ERP_SLOT) { - int slot_time; - - ah->ah_short_slot = bss_conf->use_short_slot; - slot_time = ath5k_hw_get_default_slottime(ah) + - 3 * ah->ah_coverage_class; - ath5k_hw_set_ifs_intervals(ah, slot_time); - } - - if (changes & BSS_CHANGED_ASSOC) { - avf->assoc = bss_conf->assoc; - if (bss_conf->assoc) - ah->assoc = bss_conf->assoc; - else - ah->assoc = ath5k_any_vif_assoc(ah); - - if (ah->opmode == NL80211_IFTYPE_STATION) - ath5k_set_beacon_filter(hw, ah->assoc); - ath5k_hw_set_ledstate(ah, ah->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); - if (bss_conf->assoc) { - ATH5K_DBG(ah, ATH5K_DEBUG_ANY, - "Bss Info ASSOC %d, bssid: %pM\n", - bss_conf->aid, common->curbssid); - common->curaid = bss_conf->aid; - ath5k_hw_set_bssid(ah); - /* Once ANI is available you would start it here */ - } - } - - if (changes & BSS_CHANGED_BEACON) { - spin_lock_irqsave(&ah->block, flags); - ath5k_beacon_update(hw, vif); - spin_unlock_irqrestore(&ah->block, flags); - } - - if (changes & BSS_CHANGED_BEACON_ENABLED) - ah->enable_beacon = bss_conf->enable_beacon; - - if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_BEACON_INT)) - ath5k_beacon_config(ah); - - mutex_unlock(&ah->lock); -} - - -static u64 -ath5k_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) -{ - u32 mfilt[2], val; - u8 pos; - struct netdev_hw_addr *ha; - - mfilt[0] = 0; - mfilt[1] = 1; - - netdev_hw_addr_list_for_each(ha, mc_list) { - /* calculate XOR of eight 6-bit values */ - val = get_unaligned_le32(ha->addr + 0); - pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - val = get_unaligned_le32(ha->addr + 3); - pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - pos &= 0x3f; - mfilt[pos / 32] |= (1 << (pos % 32)); - /* XXX: we might be able to just do this instead, - * but not sure, needs testing, if we do use this we'd - * need to inform below not to reset the mcast */ - /* ath5k_hw_set_mcast_filterindex(ah, - * ha->addr[5]); */ - } - - return ((u64)(mfilt[1]) << 32) | mfilt[0]; -} - - -/* - * o always accept unicast, broadcast, and multicast traffic - * o multicast traffic for all BSSIDs will be enabled if mac80211 - * says it should be - * o maintain current state of phy ofdm or phy cck error reception. - * If the hardware detects any of these type of errors then - * ath5k_hw_get_rx_filter() will pass to us the respective - * hardware filters to be able to receive these type of frames. - * o probe request frames are accepted only when operating in - * hostap, adhoc, or monitor modes - * o enable promiscuous mode according to the interface state - * o accept beacons: - * - when operating in adhoc mode so the 802.11 layer creates - * node table entries for peers, - * - when operating in station mode for collecting rssi data when - * the station is otherwise quiet, or - * - when scanning - */ -static void -ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, - unsigned int *new_flags, u64 multicast) -{ -#define SUPPORTED_FIF_FLAGS \ - (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ - FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ - FIF_BCN_PRBRESP_PROMISC) - - struct ath5k_hw *ah = hw->priv; - u32 mfilt[2], rfilt; - struct ath5k_vif_iter_data iter_data; /* to count STA interfaces */ - - mutex_lock(&ah->lock); - - mfilt[0] = multicast; - mfilt[1] = multicast >> 32; - - /* Only deal with supported flags */ - changed_flags &= SUPPORTED_FIF_FLAGS; - *new_flags &= SUPPORTED_FIF_FLAGS; - - /* If HW detects any phy or radar errors, leave those filters on. - * Also, always enable Unicast, Broadcasts and Multicast - * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ - rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | - (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | - AR5K_RX_FILTER_MCAST); - - if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { - if (*new_flags & FIF_PROMISC_IN_BSS) - __set_bit(ATH_STAT_PROMISC, ah->status); - else - __clear_bit(ATH_STAT_PROMISC, ah->status); - } - - if (test_bit(ATH_STAT_PROMISC, ah->status)) - rfilt |= AR5K_RX_FILTER_PROM; - - /* Note, AR5K_RX_FILTER_MCAST is already enabled */ - if (*new_flags & FIF_ALLMULTI) { - mfilt[0] = ~0; - mfilt[1] = ~0; - } - - /* This is the best we can do */ - if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) - rfilt |= AR5K_RX_FILTER_PHYERR; - - /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons - * and probes for any BSSID */ - if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (ah->nvifs > 1)) - rfilt |= AR5K_RX_FILTER_BEACON; - - /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not - * set we should only pass on control frames for this - * station. This needs testing. I believe right now this - * enables *all* control frames, which is OK.. but - * but we should see if we can improve on granularity */ - if (*new_flags & FIF_CONTROL) - rfilt |= AR5K_RX_FILTER_CONTROL; - - /* Additional settings per mode -- this is per ath5k */ - - /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ - - switch (ah->opmode) { - case NL80211_IFTYPE_MESH_POINT: - rfilt |= AR5K_RX_FILTER_CONTROL | - AR5K_RX_FILTER_BEACON | - AR5K_RX_FILTER_PROBEREQ | - AR5K_RX_FILTER_PROM; - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: - rfilt |= AR5K_RX_FILTER_PROBEREQ | - AR5K_RX_FILTER_BEACON; - break; - case NL80211_IFTYPE_STATION: - if (ah->assoc) - rfilt |= AR5K_RX_FILTER_BEACON; - default: - break; - } - - iter_data.hw_macaddr = NULL; - iter_data.n_stas = 0; - iter_data.need_set_hw_addr = false; - ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, - &iter_data); - - /* Set up RX Filter */ - if (iter_data.n_stas > 1) { - /* If you have multiple STA interfaces connected to - * different APs, ARPs are not received (most of the time?) - * Enabling PROMISC appears to fix that problem. - */ - rfilt |= AR5K_RX_FILTER_PROM; - } - - /* Set filters */ - ath5k_hw_set_rx_filter(ah, rfilt); - - /* Set multicast bits */ - ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); - /* Set the cached hw filter flags, this will later actually - * be set in HW */ - ah->filter_flags = rfilt; - - mutex_unlock(&ah->lock); -} - - -static int -ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) -{ - struct ath5k_hw *ah = hw->priv; - struct ath_common *common = ath5k_hw_common(ah); - int ret = 0; - - 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: - case WLAN_CIPHER_SUITE_TKIP: - break; - case WLAN_CIPHER_SUITE_CCMP: - if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) - break; - return -EOPNOTSUPP; - default: - WARN_ON(1); - return -EINVAL; - } - - mutex_lock(&ah->lock); - - switch (cmd) { - case SET_KEY: - ret = ath_key_config(common, vif, sta, key); - if (ret >= 0) { - key->hw_key_idx = ret; - /* push IV and Michael MIC generation to stack */ - key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) - key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; - ret = 0; - } - break; - case DISABLE_KEY: - ath_key_delete(common, key); - break; - default: - ret = -EINVAL; - } - - mmiowb(); - mutex_unlock(&ah->lock); - return ret; -} - - -static void -ath5k_sw_scan_start(struct ieee80211_hw *hw) -{ - struct ath5k_hw *ah = hw->priv; - if (!ah->assoc) - ath5k_hw_set_ledstate(ah, AR5K_LED_SCAN); -} - - -static void -ath5k_sw_scan_complete(struct ieee80211_hw *hw) -{ - struct ath5k_hw *ah = hw->priv; - ath5k_hw_set_ledstate(ah, ah->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); -} - - -static int -ath5k_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) -{ - struct ath5k_hw *ah = hw->priv; - - /* Force update */ - ath5k_hw_update_mib_counters(ah); - - stats->dot11ACKFailureCount = ah->stats.ack_fail; - stats->dot11RTSFailureCount = ah->stats.rts_fail; - stats->dot11RTSSuccessCount = ah->stats.rts_ok; - stats->dot11FCSErrorCount = ah->stats.fcs_error; - - return 0; -} - - -static int -ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, - const struct ieee80211_tx_queue_params *params) -{ - struct ath5k_hw *ah = hw->priv; - struct ath5k_txq_info qi; - int ret = 0; - - if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) - return 0; - - mutex_lock(&ah->lock); - - ath5k_hw_get_tx_queueprops(ah, queue, &qi); - - qi.tqi_aifs = params->aifs; - qi.tqi_cw_min = params->cw_min; - qi.tqi_cw_max = params->cw_max; - qi.tqi_burst_time = params->txop; - - ATH5K_DBG(ah, ATH5K_DEBUG_ANY, - "Configure tx [queue %d], " - "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", - queue, params->aifs, params->cw_min, - params->cw_max, params->txop); - - if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { - ATH5K_ERR(ah, - "Unable to update hardware queue %u!\n", queue); - ret = -EIO; - } else - ath5k_hw_reset_tx_queue(ah, queue); - - mutex_unlock(&ah->lock); - - return ret; -} - - -static u64 -ath5k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct ath5k_hw *ah = hw->priv; - - return ath5k_hw_get_tsf64(ah); -} - - -static void -ath5k_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u64 tsf) -{ - struct ath5k_hw *ah = hw->priv; - - ath5k_hw_set_tsf64(ah, tsf); -} - - -static void -ath5k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -{ - struct ath5k_hw *ah = hw->priv; - - /* - * in IBSS mode we need to update the beacon timers too. - * this will also reset the TSF if we call it with 0 - */ - if (ah->opmode == NL80211_IFTYPE_ADHOC) - ath5k_beacon_update_timers(ah, 0); - else - ath5k_hw_reset_tsf(ah); -} - - -static int -ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) -{ - struct ath5k_hw *ah = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - struct ath_common *common = ath5k_hw_common(ah); - struct ath_cycle_counters *cc = &common->cc_survey; - unsigned int div = common->clockrate * 1000; - - if (idx != 0) - return -ENOENT; - - spin_lock_bh(&common->cc_lock); - ath_hw_cycle_counters_update(common); - if (cc->cycles > 0) { - ah->survey.channel_time += cc->cycles / div; - ah->survey.channel_time_busy += cc->rx_busy / div; - ah->survey.channel_time_rx += cc->rx_frame / div; - ah->survey.channel_time_tx += cc->tx_frame / div; - } - memset(cc, 0, sizeof(*cc)); - spin_unlock_bh(&common->cc_lock); - - memcpy(survey, &ah->survey, sizeof(*survey)); - - survey->channel = conf->channel; - survey->noise = ah->ah_noise_floor; - survey->filled = SURVEY_INFO_NOISE_DBM | - SURVEY_INFO_CHANNEL_TIME | - SURVEY_INFO_CHANNEL_TIME_BUSY | - SURVEY_INFO_CHANNEL_TIME_RX | - SURVEY_INFO_CHANNEL_TIME_TX; - - return 0; -} - - -/** - * ath5k_set_coverage_class - Set IEEE 802.11 coverage class - * - * @hw: struct ieee80211_hw pointer - * @coverage_class: IEEE 802.11 coverage class number - * - * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given - * coverage class. The values are persistent, they are restored after device - * reset. - */ -static void -ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) -{ - struct ath5k_hw *ah = hw->priv; - - mutex_lock(&ah->lock); - ath5k_hw_set_coverage_class(ah, coverage_class); - mutex_unlock(&ah->lock); -} - - -static int -ath5k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) -{ - struct ath5k_hw *ah = hw->priv; - - if (tx_ant == 1 && rx_ant == 1) - ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_A); - else if (tx_ant == 2 && rx_ant == 2) - ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_FIXED_B); - else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) - ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); - else - return -EINVAL; - return 0; -} - - -static int -ath5k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) -{ - struct ath5k_hw *ah = hw->priv; - - switch (ah->ah_ant_mode) { - case AR5K_ANTMODE_FIXED_A: - *tx_ant = 1; *rx_ant = 1; break; - case AR5K_ANTMODE_FIXED_B: - *tx_ant = 2; *rx_ant = 2; break; - case AR5K_ANTMODE_DEFAULT: - *tx_ant = 3; *rx_ant = 3; break; - } - return 0; -} - - -static void ath5k_get_ringparam(struct ieee80211_hw *hw, - u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) -{ - struct ath5k_hw *ah = hw->priv; - - *tx = ah->txqs[AR5K_TX_QUEUE_ID_DATA_MIN].txq_max; - - *tx_max = ATH5K_TXQ_LEN_MAX; - *rx = *rx_max = ATH_RXBUF; -} - - -static int ath5k_set_ringparam(struct ieee80211_hw *hw, u32 tx, u32 rx) -{ - struct ath5k_hw *ah = hw->priv; - u16 qnum; - - /* only support setting tx ring size for now */ - if (rx != ATH_RXBUF) - return -EINVAL; - - /* restrict tx ring size min/max */ - if (!tx || tx > ATH5K_TXQ_LEN_MAX) - return -EINVAL; - - for (qnum = 0; qnum < ARRAY_SIZE(ah->txqs); qnum++) { - if (!ah->txqs[qnum].setup) - continue; - if (ah->txqs[qnum].qnum < AR5K_TX_QUEUE_ID_DATA_MIN || - ah->txqs[qnum].qnum > AR5K_TX_QUEUE_ID_DATA_MAX) - continue; - - ah->txqs[qnum].txq_max = tx; - if (ah->txqs[qnum].txq_len >= ah->txqs[qnum].txq_max) - ieee80211_stop_queue(hw, ah->txqs[qnum].qnum); - } - - return 0; -} - - -const struct ieee80211_ops ath5k_hw_ops = { - .tx = ath5k_tx, - .start = ath5k_start, - .stop = ath5k_stop, - .add_interface = ath5k_add_interface, - /* .change_interface = not implemented */ - .remove_interface = ath5k_remove_interface, - .config = ath5k_config, - .bss_info_changed = ath5k_bss_info_changed, - .prepare_multicast = ath5k_prepare_multicast, - .configure_filter = ath5k_configure_filter, - /* .set_tim = not implemented */ - .set_key = ath5k_set_key, - /* .update_tkip_key = not implemented */ - /* .hw_scan = not implemented */ - .sw_scan_start = ath5k_sw_scan_start, - .sw_scan_complete = ath5k_sw_scan_complete, - .get_stats = ath5k_get_stats, - /* .get_tkip_seq = not implemented */ - /* .set_frag_threshold = not implemented */ - /* .set_rts_threshold = not implemented */ - /* .sta_add = not implemented */ - /* .sta_remove = not implemented */ - /* .sta_notify = not implemented */ - .conf_tx = ath5k_conf_tx, - .get_tsf = ath5k_get_tsf, - .set_tsf = ath5k_set_tsf, - .reset_tsf = ath5k_reset_tsf, - /* .tx_last_beacon = not implemented */ - /* .ampdu_action = not needed */ - .get_survey = ath5k_get_survey, - .set_coverage_class = ath5k_set_coverage_class, - /* .rfkill_poll = not implemented */ - /* .flush = not implemented */ - /* .channel_switch = not implemented */ - /* .napi_poll = not implemented */ - .set_antenna = ath5k_set_antenna, - .get_antenna = ath5k_get_antenna, - .set_ringparam = ath5k_set_ringparam, - .get_ringparam = ath5k_get_ringparam, -}; diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/pci.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/pci.c deleted file mode 100644 index 849fa060..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/pci.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2008-2009 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. - */ - -#include <linux/nl80211.h> -#include <linux/pci.h> -#include <linux/pci-aspm.h> -#include <linux/etherdevice.h> -#include <linux/module.h> -#include "../ath.h" -#include "ath5k.h" -#include "debug.h" -#include "base.h" -#include "reg.h" - -/* Known PCI ids */ -static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { - { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ - { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ - { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ - { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */ - { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */ - { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ - { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ - { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ - { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 compatible */ - { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 compatible */ - { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 compatible */ - { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 compatible */ - { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 compatible */ - { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 compatible */ - { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ - { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ - { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ - { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); - -/* return bus cachesize in 4B word units */ -static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) -{ - struct ath5k_hw *ah = (struct ath5k_hw *) common->priv; - u8 u8tmp; - - pci_read_config_byte(ah->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); - *csz = (int)u8tmp; - - /* - * This check was put in to avoid "unpleasant" consequences if - * the bootrom has not fully initialized all PCI devices. - * Sometimes the cache line size register is not set - */ - - if (*csz == 0) - *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ -} - -/* - * Read from eeprom - */ -static bool -ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data) -{ - struct ath5k_hw *ah = (struct ath5k_hw *) common->ah; - u32 status, timeout; - - /* - * Initialize EEPROM access - */ - if (ah->ah_version == AR5K_AR5210) { - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); - (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); - } else { - ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); - AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, - AR5K_EEPROM_CMD_READ); - } - - for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { - status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); - if (status & AR5K_EEPROM_STAT_RDDONE) { - if (status & AR5K_EEPROM_STAT_RDERR) - return false; - *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & - 0xffff); - return true; - } - usleep_range(15, 20); - } - - return false; -} - -int ath5k_hw_read_srev(struct ath5k_hw *ah) -{ - ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV); - return 0; -} - -/* - * Read the MAC address from eeprom or platform_data - */ -static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) -{ - u8 mac_d[ETH_ALEN] = {}; - u32 total, offset; - u16 data; - int octet; - - AR5K_EEPROM_READ(0x20, data); - - for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - AR5K_EEPROM_READ(offset, data); - - total += data; - mac_d[octet + 1] = data & 0xff; - mac_d[octet] = data >> 8; - octet += 2; - } - - if (!total || total == 3 * 0xffff) - return -EINVAL; - - memcpy(mac, mac_d, ETH_ALEN); - - return 0; -} - - -/* Common ath_bus_opts structure */ -static const struct ath_bus_ops ath_pci_bus_ops = { - .ath_bus_type = ATH_PCI, - .read_cachesize = ath5k_pci_read_cachesize, - .eeprom_read = ath5k_pci_eeprom_read, - .eeprom_read_mac = ath5k_pci_eeprom_read_mac, -}; - -/********************\ -* PCI Initialization * -\********************/ - -static int __devinit -ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - void __iomem *mem; - struct ath5k_hw *ah; - struct ieee80211_hw *hw; - int ret; - u8 csz; - - /* - * L0s needs to be disabled on all ath5k cards. - * - * For distributions shipping with CONFIG_PCIEASPM (this will be enabled - * by default in the future in 2.6.36) this will also mean both L1 and - * L0s will be disabled when a pre 1.1 PCIe device is detected. We do - * know L1 works correctly even for all ath5k pre 1.1 PCIe devices - * though but cannot currently undue the effect of a blacklist, for - * details you can read pcie_aspm_sanity_check() and see how it adjusts - * the device link capability. - * - * It may be possible in the future to implement some PCI API to allow - * drivers to override blacklists for pre 1.1 PCIe but for now it is - * best to accept that both L0s and L1 will be disabled completely for - * distributions shipping with CONFIG_PCIEASPM rather than having this - * issue present. Motivation for adding this new API will be to help - * with power consumption for some of these devices. - */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); - - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "can't enable device\n"); - goto err; - } - - /* XXX 32-bit addressing only */ - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "32-bit DMA not available\n"); - goto err_dis; - } - - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); - if (csz == 0) { - /* - * Linux 2.4.18 (at least) writes the cache line size - * register as a 16-bit wide register which is wrong. - * We must have this setup properly for rx buffer - * DMA to work so force a reasonable value here if it - * comes up zero. - */ - csz = L1_CACHE_BYTES >> 2; - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); - } - /* - * The default setting of latency timer yields poor results, - * set it to the value used by other systems. It may be worth - * tweaking this setting more. - */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); - - /* Enable bus mastering */ - pci_set_master(pdev); - - /* - * Disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, 0x41, 0); - - ret = pci_request_region(pdev, 0, "ath5k"); - if (ret) { - dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); - goto err_dis; - } - - mem = pci_iomap(pdev, 0, 0); - if (!mem) { - dev_err(&pdev->dev, "cannot remap PCI memory region\n"); - ret = -EIO; - goto err_reg; - } - - /* - * Allocate hw (mac80211 main struct) - * and hw->priv (driver private data) - */ - hw = ieee80211_alloc_hw(sizeof(*ah), &ath5k_hw_ops); - if (hw == NULL) { - dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); - ret = -ENOMEM; - goto err_map; - } - - dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); - - ah = hw->priv; - ah->hw = hw; - ah->pdev = pdev; - ah->dev = &pdev->dev; - ah->irq = pdev->irq; - ah->devid = id->device; - ah->iobase = mem; /* So we can unmap it on detach */ - - /* Initialize */ - ret = ath5k_init_ah(ah, &ath_pci_bus_ops); - if (ret) - goto err_free; - - /* Set private data */ - pci_set_drvdata(pdev, hw); - - return 0; -err_free: - ieee80211_free_hw(hw); -err_map: - pci_iounmap(pdev, mem); -err_reg: - pci_release_region(pdev, 0); -err_dis: - pci_disable_device(pdev); -err: - return ret; -} - -static void __devexit -ath5k_pci_remove(struct pci_dev *pdev) -{ - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_hw *ah = hw->priv; - - ath5k_deinit_ah(ah); - pci_iounmap(pdev, ah->iobase); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - ieee80211_free_hw(hw); -} - -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_hw *ah = hw->priv; - - ath5k_led_off(ah); - return 0; -} - -static int ath5k_pci_resume(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_hw *ah = hw->priv; - - /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state - */ - pci_write_config_byte(pdev, 0x41, 0); - - ath5k_led_enable(ah); - return 0; -} - -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); -#define ATH5K_PM_OPS (&ath5k_pm_ops) -#else -#define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ - -static struct pci_driver ath5k_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = ath5k_pci_id_table, - .probe = ath5k_pci_probe, - .remove = __devexit_p(ath5k_pci_remove), - .driver.pm = ATH5K_PM_OPS, -}; - -/* - * Module init/exit functions - */ -static int __init -init_ath5k_pci(void) -{ - int ret; - - ret = pci_register_driver(&ath5k_pci_driver); - if (ret) { - printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); - return ret; - } - - return 0; -} - -static void __exit -exit_ath5k_pci(void) -{ - pci_unregister_driver(&ath5k_pci_driver); -} - -module_init(init_ath5k_pci); -module_exit(exit_ath5k_pci); diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/pcu.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/pcu.c deleted file mode 100644 index cebfd6fd..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/pcu.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2007-2008 Matthew W. S. Bell <mentor@madwifi.org> - * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu> - * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> - * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/*********************************\ -* Protocol Control Unit Functions * -\*********************************/ - -#include <asm/unaligned.h> - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - -/** - * DOC: Protocol Control Unit (PCU) functions - * - * Protocol control unit is responsible to maintain various protocol - * properties before a frame is send and after a frame is received to/from - * baseband. To be more specific, PCU handles: - * - * - Buffering of RX and TX frames (after QCU/DCUs) - * - * - Encrypting and decrypting (using the built-in engine) - * - * - Generating ACKs, RTS/CTS frames - * - * - Maintaining TSF - * - * - FCS - * - * - Updating beacon data (with TSF etc) - * - * - Generating virtual CCA - * - * - RX/Multicast filtering - * - * - BSSID filtering - * - * - Various statistics - * - * -Different operating modes: AP, STA, IBSS - * - * Note: Most of these functions can be tweaked/bypassed so you can do - * them on sw above for debugging or research. For more infos check out PCU - * registers on reg.h. - */ - -/** - * DOC: ACK rates - * - * AR5212+ can use higher rates for ack transmission - * based on current tx rate instead of the base rate. - * It does this to better utilize channel usage. - * There is a mapping between G rates (that cover both - * CCK and OFDM) and ack rates that we use when setting - * rate -> duration table. This mapping is hw-based so - * don't change anything. - * - * To enable this functionality we must set - * ah->ah_ack_bitrate_high to true else base rate is - * used (1Mb for CCK, 6Mb for OFDM). - */ -static const unsigned int ack_rates_high[] = -/* Tx -> ACK */ -/* 1Mb -> 1Mb */ { 0, -/* 2MB -> 2Mb */ 1, -/* 5.5Mb -> 2Mb */ 1, -/* 11Mb -> 2Mb */ 1, -/* 6Mb -> 6Mb */ 4, -/* 9Mb -> 6Mb */ 4, -/* 12Mb -> 12Mb */ 6, -/* 18Mb -> 12Mb */ 6, -/* 24Mb -> 24Mb */ 8, -/* 36Mb -> 24Mb */ 8, -/* 48Mb -> 24Mb */ 8, -/* 54Mb -> 24Mb */ 8 }; - -/*******************\ -* Helper functions * -\*******************/ - -/** - * ath5k_hw_get_frame_duration() - Get tx time of a frame - * @ah: The &struct ath5k_hw - * @len: Frame's length in bytes - * @rate: The @struct ieee80211_rate - * @shortpre: Indicate short preample - * - * Calculate tx duration of a frame given it's rate and length - * It extends ieee80211_generic_frame_duration for non standard - * bwmodes. - */ -int -ath5k_hw_get_frame_duration(struct ath5k_hw *ah, - int len, struct ieee80211_rate *rate, bool shortpre) -{ - int sifs, preamble, plcp_bits, sym_time; - int bitrate, bits, symbols, symbol_bits; - int dur; - - /* Fallback */ - if (!ah->ah_bwmode) { - __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw, - NULL, len, rate); - - /* subtract difference between long and short preamble */ - dur = le16_to_cpu(raw_dur); - if (shortpre) - dur -= 96; - - return dur; - } - - bitrate = rate->bitrate; - preamble = AR5K_INIT_OFDM_PREAMPLE_TIME; - plcp_bits = AR5K_INIT_OFDM_PLCP_BITS; - sym_time = AR5K_INIT_OFDM_SYMBOL_TIME; - - switch (ah->ah_bwmode) { - case AR5K_BWMODE_40MHZ: - sifs = AR5K_INIT_SIFS_TURBO; - preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN; - break; - case AR5K_BWMODE_10MHZ: - sifs = AR5K_INIT_SIFS_HALF_RATE; - preamble *= 2; - sym_time *= 2; - break; - case AR5K_BWMODE_5MHZ: - sifs = AR5K_INIT_SIFS_QUARTER_RATE; - preamble *= 4; - sym_time *= 4; - break; - default: - sifs = AR5K_INIT_SIFS_DEFAULT_BG; - break; - } - - bits = plcp_bits + (len << 3); - /* Bit rate is in 100Kbits */ - symbol_bits = bitrate * sym_time; - symbols = DIV_ROUND_UP(bits * 10, symbol_bits); - - dur = sifs + preamble + (sym_time * symbols); - - return dur; -} - -/** - * ath5k_hw_get_default_slottime() - Get the default slot time for current mode - * @ah: The &struct ath5k_hw - */ -unsigned int -ath5k_hw_get_default_slottime(struct ath5k_hw *ah) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - unsigned int slot_time; - - switch (ah->ah_bwmode) { - case AR5K_BWMODE_40MHZ: - slot_time = AR5K_INIT_SLOT_TIME_TURBO; - break; - case AR5K_BWMODE_10MHZ: - slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE; - break; - case AR5K_BWMODE_5MHZ: - slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; - break; - case AR5K_BWMODE_DEFAULT: - default: - slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; - if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot) - slot_time = AR5K_INIT_SLOT_TIME_B; - break; - } - - return slot_time; -} - -/** - * ath5k_hw_get_default_sifs() - Get the default SIFS for current mode - * @ah: The &struct ath5k_hw - */ -unsigned int -ath5k_hw_get_default_sifs(struct ath5k_hw *ah) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - unsigned int sifs; - - switch (ah->ah_bwmode) { - case AR5K_BWMODE_40MHZ: - sifs = AR5K_INIT_SIFS_TURBO; - break; - case AR5K_BWMODE_10MHZ: - sifs = AR5K_INIT_SIFS_HALF_RATE; - break; - case AR5K_BWMODE_5MHZ: - sifs = AR5K_INIT_SIFS_QUARTER_RATE; - break; - case AR5K_BWMODE_DEFAULT: - sifs = AR5K_INIT_SIFS_DEFAULT_BG; - default: - if (channel->band == IEEE80211_BAND_5GHZ) - sifs = AR5K_INIT_SIFS_DEFAULT_A; - break; - } - - return sifs; -} - -/** - * ath5k_hw_update_mib_counters() - Update MIB counters (mac layer statistics) - * @ah: The &struct ath5k_hw - * - * Reads MIB counters from PCU and updates sw statistics. Is called after a - * MIB interrupt, because one of these counters might have reached their maximum - * and triggered the MIB interrupt, to let us read and clear the counter. - * - * NOTE: Is called in interrupt context! - */ -void -ath5k_hw_update_mib_counters(struct ath5k_hw *ah) -{ - struct ath5k_statistics *stats = &ah->stats; - - /* Read-And-Clear */ - stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); - stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); - stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK); - stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); - stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); -} - - -/******************\ -* ACK/CTS Timeouts * -\******************/ - -/** - * ath5k_hw_write_rate_duration() - Fill rate code to duration table - * @ah: The &struct ath5k_hw - * - * Write the rate code to duration table upon hw reset. This is a helper for - * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on - * the hardware, based on current mode, for each rate. The rates which are - * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have - * different rate code so we write their value twice (one for long preamble - * and one for short). - * - * Note: Band doesn't matter here, if we set the values for OFDM it works - * on both a and g modes. So all we have to do is set values for all g rates - * that include all OFDM and CCK rates. - * - */ -static inline void -ath5k_hw_write_rate_duration(struct ath5k_hw *ah) -{ - struct ieee80211_rate *rate; - unsigned int i; - /* 802.11g covers both OFDM and CCK */ - u8 band = IEEE80211_BAND_2GHZ; - - /* Write rate duration table */ - for (i = 0; i < ah->sbands[band].n_bitrates; i++) { - u32 reg; - u16 tx_time; - - if (ah->ah_ack_bitrate_high) - rate = &ah->sbands[band].bitrates[ack_rates_high[i]]; - /* CCK -> 1Mb */ - else if (i < 4) - rate = &ah->sbands[band].bitrates[0]; - /* OFDM -> 6Mb */ - else - rate = &ah->sbands[band].bitrates[4]; - - /* Set ACK timeout */ - reg = AR5K_RATE_DUR(rate->hw_value); - - /* An ACK frame consists of 10 bytes. If you add the FCS, - * which ieee80211_generic_frame_duration() adds, - * its 14 bytes. Note we use the control rate and not the - * actual rate for this rate. See mac80211 tx.c - * ieee80211_duration() for a brief description of - * what rate we should choose to TX ACKs. */ - tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); - - ath5k_hw_reg_write(ah, tx_time, reg); - - if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) - continue; - - tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); - ath5k_hw_reg_write(ah, tx_time, - reg + (AR5K_SET_SHORT_PREAMBLE << 2)); - } -} - -/** - * ath5k_hw_set_ack_timeout() - Set ACK timeout on PCU - * @ah: The &struct ath5k_hw - * @timeout: Timeout in usec - */ -static int -ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) -{ - if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) - <= timeout) - return -EINVAL; - - AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, - ath5k_hw_htoclock(ah, timeout)); - - return 0; -} - -/** - * ath5k_hw_set_cts_timeout() - Set CTS timeout on PCU - * @ah: The &struct ath5k_hw - * @timeout: Timeout in usec - */ -static int -ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) -{ - if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) - <= timeout) - return -EINVAL; - - AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, - ath5k_hw_htoclock(ah, timeout)); - - return 0; -} - - -/*******************\ -* RX filter Control * -\*******************/ - -/** - * ath5k_hw_set_lladdr() - Set station id - * @ah: The &struct ath5k_hw - * @mac: The card's mac address (array of octets) - * - * Set station id on hw using the provided mac address - */ -int -ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) -{ - struct ath_common *common = ath5k_hw_common(ah); - u32 low_id, high_id; - u32 pcu_reg; - - /* Set new station ID */ - memcpy(common->macaddr, mac, ETH_ALEN); - - pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; - - low_id = get_unaligned_le32(mac); - high_id = get_unaligned_le16(mac + 4); - - ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); - ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); - - return 0; -} - -/** - * ath5k_hw_set_bssid() - Set current BSSID on hw - * @ah: The &struct ath5k_hw - * - * Sets the current BSSID and BSSID mask we have from the - * common struct into the hardware - */ -void -ath5k_hw_set_bssid(struct ath5k_hw *ah) -{ - struct ath_common *common = ath5k_hw_common(ah); - u16 tim_offset = 0; - - /* - * Set BSSID mask on 5212 - */ - if (ah->ah_version == AR5K_AR5212) - ath_hw_setbssidmask(common); - - /* - * Set BSSID - */ - ath5k_hw_reg_write(ah, - get_unaligned_le32(common->curbssid), - AR5K_BSS_ID0); - ath5k_hw_reg_write(ah, - get_unaligned_le16(common->curbssid + 4) | - ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S), - AR5K_BSS_ID1); - - if (common->curaid == 0) { - ath5k_hw_disable_pspoll(ah); - return; - } - - AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM, - tim_offset ? tim_offset + 4 : 0); - - ath5k_hw_enable_pspoll(ah, NULL, 0); -} - -/** - * ath5k_hw_set_bssid_mask() - Filter out bssids we listen - * @ah: The &struct ath5k_hw - * @mask: The BSSID mask to set (array of octets) - * - * BSSID masking is a method used by AR5212 and newer hardware to inform PCU - * which bits of the interface's MAC address should be looked at when trying - * to decide which packets to ACK. In station mode and AP mode with a single - * BSS every bit matters since we lock to only one BSS. In AP mode with - * multiple BSSes (virtual interfaces) not every bit matters because hw must - * accept frames for all BSSes and so we tweak some bits of our mac address - * in order to have multiple BSSes. - * - * For more information check out ../hw.c of the common ath module. - */ -void -ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) -{ - struct ath_common *common = ath5k_hw_common(ah); - - /* Cache bssid mask so that we can restore it - * on reset */ - memcpy(common->bssidmask, mask, ETH_ALEN); - if (ah->ah_version == AR5K_AR5212) - ath_hw_setbssidmask(common); -} - -/** - * ath5k_hw_set_mcast_filter() - Set multicast filter - * @ah: The &struct ath5k_hw - * @filter0: Lower 32bits of muticast filter - * @filter1: Higher 16bits of multicast filter - */ -void -ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) -{ - ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); - ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); -} - -/** - * ath5k_hw_get_rx_filter() - Get current rx filter - * @ah: The &struct ath5k_hw - * - * Returns the RX filter by reading rx filter and - * phy error filter registers. RX filter is used - * to set the allowed frame types that PCU will accept - * and pass to the driver. For a list of frame types - * check out reg.h. - */ -u32 -ath5k_hw_get_rx_filter(struct ath5k_hw *ah) -{ - u32 data, filter = 0; - - filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); - - /*Radar detection for 5212*/ - if (ah->ah_version == AR5K_AR5212) { - data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL); - - if (data & AR5K_PHY_ERR_FIL_RADAR) - filter |= AR5K_RX_FILTER_RADARERR; - if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK)) - filter |= AR5K_RX_FILTER_PHYERR; - } - - return filter; -} - -/** - * ath5k_hw_set_rx_filter() - Set rx filter - * @ah: The &struct ath5k_hw - * @filter: RX filter mask (see reg.h) - * - * Sets RX filter register and also handles PHY error filter - * register on 5212 and newer chips so that we have proper PHY - * error reporting. - */ -void -ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) -{ - u32 data = 0; - - /* Set PHY error filter register on 5212*/ - if (ah->ah_version == AR5K_AR5212) { - if (filter & AR5K_RX_FILTER_RADARERR) - data |= AR5K_PHY_ERR_FIL_RADAR; - if (filter & AR5K_RX_FILTER_PHYERR) - data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK; - } - - /* - * The AR5210 uses promiscuous mode to detect radar activity - */ - if (ah->ah_version == AR5K_AR5210 && - (filter & AR5K_RX_FILTER_RADARERR)) { - filter &= ~AR5K_RX_FILTER_RADARERR; - filter |= AR5K_RX_FILTER_PROM; - } - - /*Zero length DMA (phy error reporting) */ - if (data) - AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); - else - AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); - - /*Write RX Filter register*/ - ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER); - - /*Write PHY error filter register on 5212*/ - if (ah->ah_version == AR5K_AR5212) - ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL); - -} - - -/****************\ -* Beacon control * -\****************/ - -#define ATH5K_MAX_TSF_READ 10 - -/** - * ath5k_hw_get_tsf64() - Get the full 64bit TSF - * @ah: The &struct ath5k_hw - * - * Returns the current TSF - */ -u64 -ath5k_hw_get_tsf64(struct ath5k_hw *ah) -{ - u32 tsf_lower, tsf_upper1, tsf_upper2; - int i; - unsigned long flags; - - /* This code is time critical - we don't want to be interrupted here */ - local_irq_save(flags); - - /* - * While reading TSF upper and then lower part, the clock is still - * counting (or jumping in case of IBSS merge) so we might get - * inconsistent values. To avoid this, we read the upper part again - * and check it has not been changed. We make the hypothesis that a - * maximum of 3 changes can happens in a row (we use 10 as a safe - * value). - * - * Impact on performance is pretty small, since in most cases, only - * 3 register reads are needed. - */ - - tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32); - for (i = 0; i < ATH5K_MAX_TSF_READ; i++) { - tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32); - tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32); - if (tsf_upper2 == tsf_upper1) - break; - tsf_upper1 = tsf_upper2; - } - - local_irq_restore(flags); - - WARN_ON(i == ATH5K_MAX_TSF_READ); - - return ((u64)tsf_upper1 << 32) | tsf_lower; -} - -#undef ATH5K_MAX_TSF_READ - -/** - * ath5k_hw_set_tsf64() - Set a new 64bit TSF - * @ah: The &struct ath5k_hw - * @tsf64: The new 64bit TSF - * - * Sets the new TSF - */ -void -ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64) -{ - ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32); - ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32); -} - -/** - * ath5k_hw_reset_tsf() - Force a TSF reset - * @ah: The &struct ath5k_hw - * - * Forces a TSF reset on PCU - */ -void -ath5k_hw_reset_tsf(struct ath5k_hw *ah) -{ - u32 val; - - val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF; - - /* - * Each write to the RESET_TSF bit toggles a hardware internal - * signal to reset TSF, but if left high it will cause a TSF reset - * on the next chip reset as well. Thus we always write the value - * twice to clear the signal. - */ - ath5k_hw_reg_write(ah, val, AR5K_BEACON); - ath5k_hw_reg_write(ah, val, AR5K_BEACON); -} - -/** - * ath5k_hw_init_beacon_timers() - Initialize beacon timers - * @ah: The &struct ath5k_hw - * @next_beacon: Next TBTT - * @interval: Current beacon interval - * - * This function is used to initialize beacon timers based on current - * operation mode and settings. - */ -void -ath5k_hw_init_beacon_timers(struct ath5k_hw *ah, u32 next_beacon, u32 interval) -{ - u32 timer1, timer2, timer3; - - /* - * Set the additional timers by mode - */ - switch (ah->opmode) { - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_STATION: - /* In STA mode timer1 is used as next wakeup - * timer and timer2 as next CFP duration start - * timer. Both in 1/8TUs. */ - /* TODO: PCF handling */ - if (ah->ah_version == AR5K_AR5210) { - timer1 = 0xffffffff; - timer2 = 0xffffffff; - } else { - timer1 = 0x0000ffff; - timer2 = 0x0007ffff; - } - /* Mark associated AP as PCF incapable for now */ - AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF); - break; - case NL80211_IFTYPE_ADHOC: - AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM); - default: - /* On non-STA modes timer1 is used as next DMA - * beacon alert (DBA) timer and timer2 as next - * software beacon alert. Both in 1/8TUs. */ - timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3; - timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3; - break; - } - - /* Timer3 marks the end of our ATIM window - * a zero length window is not allowed because - * we 'll get no beacons */ - timer3 = next_beacon + 1; - - /* - * Set the beacon register and enable all timers. - */ - /* When in AP or Mesh Point mode zero timer0 to start TSF */ - if (ah->opmode == NL80211_IFTYPE_AP || - ah->opmode == NL80211_IFTYPE_MESH_POINT) - ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); - - ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); - ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1); - ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2); - ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3); - - /* Force a TSF reset if requested and enable beacons */ - if (interval & AR5K_BEACON_RESET_TSF) - ath5k_hw_reset_tsf(ah); - - ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD | - AR5K_BEACON_ENABLE), - AR5K_BEACON); - - /* Flush any pending BMISS interrupts on ISR by - * performing a clear-on-write operation on PISR - * register for the BMISS bit (writing a bit on - * ISR toggles a reset for that bit and leaves - * the remaining bits intact) */ - if (ah->ah_version == AR5K_AR5210) - ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR); - else - ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR); - - /* TODO: Set enhanced sleep registers on AR5212 - * based on vif->bss_conf params, until then - * disable power save reporting.*/ - AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV); - -} - -/** - * ath5k_check_timer_win() - Check if timer B is timer A + window - * @a: timer a (before b) - * @b: timer b (after a) - * @window: difference between a and b - * @intval: timers are increased by this interval - * - * This helper function checks if timer B is timer A + window and covers - * cases where timer A or B might have already been updated or wrapped - * around (Timers are 16 bit). - * - * Returns true if O.K. - */ -static inline bool -ath5k_check_timer_win(int a, int b, int window, int intval) -{ - /* - * 1.) usually B should be A + window - * 2.) A already updated, B not updated yet - * 3.) A already updated and has wrapped around - * 4.) B has wrapped around - */ - if ((b - a == window) || /* 1.) */ - (a - b == intval - window) || /* 2.) */ - ((a | 0x10000) - b == intval - window) || /* 3.) */ - ((b | 0x10000) - a == window)) /* 4.) */ - return true; /* O.K. */ - return false; -} - -/** - * ath5k_hw_check_beacon_timers() - Check if the beacon timers are correct - * @ah: The &struct ath5k_hw - * @intval: beacon interval - * - * This is a workaround for IBSS mode - * - * The need for this function arises from the fact that we have 4 separate - * HW timer registers (TIMER0 - TIMER3), which are closely related to the - * next beacon target time (NBTT), and that the HW updates these timers - * separately based on the current TSF value. The hardware increments each - * timer by the beacon interval, when the local TSF converted to TU is equal - * to the value stored in the timer. - * - * The reception of a beacon with the same BSSID can update the local HW TSF - * at any time - this is something we can't avoid. If the TSF jumps to a - * time which is later than the time stored in a timer, this timer will not - * be updated until the TSF in TU wraps around at 16 bit (the size of the - * timers) and reaches the time which is stored in the timer. - * - * The problem is that these timers are closely related to TIMER0 (NBTT) and - * that they define a time "window". When the TSF jumps between two timers - * (e.g. ATIM and NBTT), the one in the past will be left behind (not - * updated), while the one in the future will be updated every beacon - * interval. This causes the window to get larger, until the TSF wraps - * around as described above and the timer which was left behind gets - * updated again. But - because the beacon interval is usually not an exact - * divisor of the size of the timers (16 bit), an unwanted "window" between - * these timers has developed! - * - * This is especially important with the ATIM window, because during - * the ATIM window only ATIM frames and no data frames are allowed to be - * sent, which creates transmission pauses after each beacon. This symptom - * has been described as "ramping ping" because ping times increase linearly - * for some time and then drop down again. A wrong window on the DMA beacon - * timer has the same effect, so we check for these two conditions. - * - * Returns true if O.K. - */ -bool -ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval) -{ - unsigned int nbtt, atim, dma; - - nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0); - atim = ath5k_hw_reg_read(ah, AR5K_TIMER3); - dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3; - - /* NOTE: SWBA is different. Having a wrong window there does not - * stop us from sending data and this condition is caught by - * other means (SWBA interrupt) */ - - if (ath5k_check_timer_win(nbtt, atim, 1, intval) && - ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP, - intval)) - return true; /* O.K. */ - return false; -} - -/** - * ath5k_hw_set_coverage_class() - Set IEEE 802.11 coverage class - * @ah: The &struct ath5k_hw - * @coverage_class: IEEE 802.11 coverage class number - * - * Sets IFS intervals and ACK/CTS timeouts for given coverage class. - */ -void -ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class) -{ - /* As defined by IEEE 802.11-2007 17.3.8.6 */ - int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class; - int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time; - int cts_timeout = ack_timeout; - - ath5k_hw_set_ifs_intervals(ah, slot_time); - ath5k_hw_set_ack_timeout(ah, ack_timeout); - ath5k_hw_set_cts_timeout(ah, cts_timeout); - - ah->ah_coverage_class = coverage_class; -} - -/***************************\ -* Init/Start/Stop functions * -\***************************/ - -/** - * ath5k_hw_start_rx_pcu() - Start RX engine - * @ah: The &struct ath5k_hw - * - * Starts RX engine on PCU so that hw can process RXed frames - * (ACK etc). - * - * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma - */ -void -ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) -{ - AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); -} - -/** - * at5k_hw_stop_rx_pcu() - Stop RX engine - * @ah: The &struct ath5k_hw - * - * Stops RX engine on PCU - */ -void -ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) -{ - AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); -} - -/** - * ath5k_hw_set_opmode() - Set PCU operating mode - * @ah: The &struct ath5k_hw - * @op_mode: One of enum nl80211_iftype - * - * Configure PCU for the various operating modes (AP/STA etc) - */ -int -ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) -{ - struct ath_common *common = ath5k_hw_common(ah); - u32 pcu_reg, beacon_reg, low_id, high_id; - - ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode %d\n", op_mode); - - /* Preserve rest settings */ - pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; - pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP - | AR5K_STA_ID1_KEYSRCH_MODE - | (ah->ah_version == AR5K_AR5210 ? - (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0)); - - beacon_reg = 0; - - switch (op_mode) { - case NL80211_IFTYPE_ADHOC: - pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; - beacon_reg |= AR5K_BCR_ADHOC; - if (ah->ah_version == AR5K_AR5210) - pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; - else - AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); - break; - - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_MESH_POINT: - pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE; - beacon_reg |= AR5K_BCR_AP; - if (ah->ah_version == AR5K_AR5210) - pcu_reg |= AR5K_STA_ID1_NO_PSPOLL; - else - AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS); - break; - - case NL80211_IFTYPE_STATION: - pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE - | (ah->ah_version == AR5K_AR5210 ? - AR5K_STA_ID1_PWR_SV : 0); - case NL80211_IFTYPE_MONITOR: - pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE - | (ah->ah_version == AR5K_AR5210 ? - AR5K_STA_ID1_NO_PSPOLL : 0); - break; - - default: - return -EINVAL; - } - - /* - * Set PCU registers - */ - low_id = get_unaligned_le32(common->macaddr); - high_id = get_unaligned_le16(common->macaddr + 4); - ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); - ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); - - /* - * Set Beacon Control Register on 5210 - */ - if (ah->ah_version == AR5K_AR5210) - ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); - - return 0; -} - -/** - * ath5k_hw_pcu_init() - Initialize PCU - * @ah: The &struct ath5k_hw - * @op_mode: One of enum nl80211_iftype - * @mode: One of enum ath5k_driver_mode - * - * This function is used to initialize PCU by setting current - * operation mode and various other settings. - */ -void -ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode) -{ - /* Set bssid and bssid mask */ - ath5k_hw_set_bssid(ah); - - /* Set PCU config */ - ath5k_hw_set_opmode(ah, op_mode); - - /* Write rate duration table only on AR5212 and if - * virtual interface has already been brought up - * XXX: rethink this after new mode changes to - * mac80211 are integrated */ - if (ah->ah_version == AR5K_AR5212 && - ah->nvifs) - ath5k_hw_write_rate_duration(ah); - - /* Set RSSI/BRSSI thresholds - * - * Note: If we decide to set this value - * dynamically, have in mind that when AR5K_RSSI_THR - * register is read it might return 0x40 if we haven't - * wrote anything to it plus BMISS RSSI threshold is zeroed. - * So doing a save/restore procedure here isn't the right - * choice. Instead store it on ath5k_hw */ - ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | - AR5K_TUNE_BMISS_THRES << - AR5K_RSSI_THR_BMISS_S), - AR5K_RSSI_THR); - - /* MIC QoS support */ - if (ah->ah_mac_srev >= AR5K_SREV_AR2413) { - ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL); - ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL); - } - - /* QoS NOACK Policy */ - if (ah->ah_version == AR5K_AR5212) { - ath5k_hw_reg_write(ah, - AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) | - AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) | - AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET), - AR5K_QOS_NOACK); - } - - /* Restore slot time and ACK timeouts */ - if (ah->ah_coverage_class > 0) - ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class); - - /* Set ACK bitrate mode (see ack_rates_high) */ - if (ah->ah_version == AR5K_AR5212) { - u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; - if (ah->ah_ack_bitrate_high) - AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); - else - AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); - } - return; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/phy.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/phy.c deleted file mode 100644 index 3a284548..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/phy.c +++ /dev/null @@ -1,3950 +0,0 @@ -/* - * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> - * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org> - * - * Permission to use, copy, modify, and 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. - * - */ - -/***********************\ -* PHY related functions * -\***********************/ - -#include <linux/delay.h> -#include <linux/slab.h> -#include <asm/unaligned.h> - -#include "ath5k.h" -#include "reg.h" -#include "rfbuffer.h" -#include "rfgain.h" -#include "../regd.h" - - -/** - * DOC: PHY related functions - * - * Here we handle the low-level functions related to baseband - * and analog frontend (RF) parts. This is by far the most complex - * part of the hw code so make sure you know what you are doing. - * - * Here is a list of what this is all about: - * - * - Channel setting/switching - * - * - Automatic Gain Control (AGC) calibration - * - * - Noise Floor calibration - * - * - I/Q imbalance calibration (QAM correction) - * - * - Calibration due to thermal changes (gain_F) - * - * - Spur noise mitigation - * - * - RF/PHY initialization for the various operating modes and bwmodes - * - * - Antenna control - * - * - TX power control per channel/rate/packet type - * - * Also have in mind we never got documentation for most of these - * functions, what we have comes mostly from Atheros's code, reverse - * engineering and patent docs/presentations etc. - */ - - -/******************\ -* Helper functions * -\******************/ - -/** - * ath5k_hw_radio_revision() - Get the PHY Chip revision - * @ah: The &struct ath5k_hw - * @band: One of enum ieee80211_band - * - * Returns the revision number of a 2GHz, 5GHz or single chip - * radio. - */ -u16 -ath5k_hw_radio_revision(struct ath5k_hw *ah, enum ieee80211_band band) -{ - unsigned int i; - u32 srev; - u16 ret; - - /* - * Set the radio chip access register - */ - switch (band) { - case IEEE80211_BAND_2GHZ: - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0)); - break; - case IEEE80211_BAND_5GHZ: - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); - break; - default: - return 0; - } - - usleep_range(2000, 2500); - - /* ...wait until PHY is ready and read the selected radio revision */ - ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34)); - - for (i = 0; i < 8; i++) - ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20)); - - if (ah->ah_version == AR5K_AR5210) { - srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf; - ret = (u16)ath5k_hw_bitswap(srev, 4) + 1; - } else { - srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff; - ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) | - ((srev & 0x0f) << 4), 8); - } - - /* Reset to the 5GHz mode */ - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); - - return ret; -} - -/** - * ath5k_channel_ok() - Check if a channel is supported by the hw - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * Note: We don't do any regulatory domain checks here, it's just - * a sanity check. - */ -bool -ath5k_channel_ok(struct ath5k_hw *ah, struct ieee80211_channel *channel) -{ - u16 freq = channel->center_freq; - - /* Check if the channel is in our supported range */ - if (channel->band == IEEE80211_BAND_2GHZ) { - if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) && - (freq <= ah->ah_capabilities.cap_range.range_2ghz_max)) - return true; - } else if (channel->band == IEEE80211_BAND_5GHZ) - if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) && - (freq <= ah->ah_capabilities.cap_range.range_5ghz_max)) - return true; - - return false; -} - -/** - * ath5k_hw_chan_has_spur_noise() - Check if channel is sensitive to spur noise - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - */ -bool -ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - u8 refclk_freq; - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) - refclk_freq = 40; - else - refclk_freq = 32; - - if ((channel->center_freq % refclk_freq != 0) && - ((channel->center_freq % refclk_freq < 10) || - (channel->center_freq % refclk_freq > 22))) - return true; - else - return false; -} - -/** - * ath5k_hw_rfb_op() - Perform an operation on the given RF Buffer - * @ah: The &struct ath5k_hw - * @rf_regs: The struct ath5k_rf_reg - * @val: New value - * @reg_id: RF register ID - * @set: Indicate we need to swap data - * - * This is an internal function used to modify RF Banks before - * writing them to AR5K_RF_BUFFER. Check out rfbuffer.h for more - * infos. - */ -static unsigned int -ath5k_hw_rfb_op(struct ath5k_hw *ah, const struct ath5k_rf_reg *rf_regs, - u32 val, u8 reg_id, bool set) -{ - const struct ath5k_rf_reg *rfreg = NULL; - u8 offset, bank, num_bits, col, position; - u16 entry; - u32 mask, data, last_bit, bits_shifted, first_bit; - u32 *rfb; - s32 bits_left; - int i; - - data = 0; - rfb = ah->ah_rf_banks; - - for (i = 0; i < ah->ah_rf_regs_count; i++) { - if (rf_regs[i].index == reg_id) { - rfreg = &rf_regs[i]; - break; - } - } - - if (rfb == NULL || rfreg == NULL) { - ATH5K_PRINTF("Rf register not found!\n"); - /* should not happen */ - return 0; - } - - bank = rfreg->bank; - num_bits = rfreg->field.len; - first_bit = rfreg->field.pos; - col = rfreg->field.col; - - /* first_bit is an offset from bank's - * start. Since we have all banks on - * the same array, we use this offset - * to mark each bank's start */ - offset = ah->ah_offset[bank]; - - /* Boundary check */ - if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) { - ATH5K_PRINTF("invalid values at offset %u\n", offset); - return 0; - } - - entry = ((first_bit - 1) / 8) + offset; - position = (first_bit - 1) % 8; - - if (set) - data = ath5k_hw_bitswap(val, num_bits); - - for (bits_shifted = 0, bits_left = num_bits; bits_left > 0; - position = 0, entry++) { - - last_bit = (position + bits_left > 8) ? 8 : - position + bits_left; - - mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) << - (col * 8); - - if (set) { - rfb[entry] &= ~mask; - rfb[entry] |= ((data << position) << (col * 8)) & mask; - data >>= (8 - position); - } else { - data |= (((rfb[entry] & mask) >> (col * 8)) >> position) - << bits_shifted; - bits_shifted += last_bit - position; - } - - bits_left -= 8 - position; - } - - data = set ? 1 : ath5k_hw_bitswap(data, num_bits); - - return data; -} - -/** - * ath5k_hw_write_ofdm_timings() - set OFDM timings on AR5212 - * @ah: the &struct ath5k_hw - * @channel: the currently set channel upon reset - * - * Write the delta slope coefficient (used on pilot tracking ?) for OFDM - * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init. - * - * Since delta slope is floating point we split it on its exponent and - * mantissa and provide these values on hw. - * - * For more infos i think this patent is related - * "http://www.freepatentsonline.com/7184495.html" - */ -static inline int -ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - /* Get exponent and mantissa and set it */ - u32 coef_scaled, coef_exp, coef_man, - ds_coef_exp, ds_coef_man, clock; - - BUG_ON(!(ah->ah_version == AR5K_AR5212) || - (channel->hw_value == AR5K_MODE_11B)); - - /* Get coefficient - * ALGO: coef = (5 * clock / carrier_freq) / 2 - * we scale coef by shifting clock value by 24 for - * better precision since we use integers */ - switch (ah->ah_bwmode) { - case AR5K_BWMODE_40MHZ: - clock = 40 * 2; - break; - case AR5K_BWMODE_10MHZ: - clock = 40 / 2; - break; - case AR5K_BWMODE_5MHZ: - clock = 40 / 4; - break; - default: - clock = 40; - break; - } - coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; - - /* Get exponent - * ALGO: coef_exp = 14 - highest set bit position */ - coef_exp = ilog2(coef_scaled); - - /* Doesn't make sense if it's zero*/ - if (!coef_scaled || !coef_exp) - return -EINVAL; - - /* Note: we've shifted coef_scaled by 24 */ - coef_exp = 14 - (coef_exp - 24); - - - /* Get mantissa (significant digits) - * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ - coef_man = coef_scaled + - (1 << (24 - coef_exp - 1)); - - /* Calculate delta slope coefficient exponent - * and mantissa (remove scaling) and set them on hw */ - ds_coef_man = coef_man >> (24 - coef_exp); - ds_coef_exp = coef_exp - 16; - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, - AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, - AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); - - return 0; -} - -/** - * ath5k_hw_phy_disable() - Disable PHY - * @ah: The &struct ath5k_hw - */ -int ath5k_hw_phy_disable(struct ath5k_hw *ah) -{ - /*Just a try M.F.*/ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); - - return 0; -} - -/** - * ath5k_hw_wait_for_synth() - Wait for synth to settle - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - */ -static void -ath5k_hw_wait_for_synth(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - /* - * On 5211+ read activation -> rx delay - * and use it (100ns steps). - */ - if (ah->ah_version != AR5K_AR5210) { - u32 delay; - delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & - AR5K_PHY_RX_DELAY_M; - delay = (channel->hw_value == AR5K_MODE_11B) ? - ((delay << 2) / 22) : (delay / 10); - if (ah->ah_bwmode == AR5K_BWMODE_10MHZ) - delay = delay << 1; - if (ah->ah_bwmode == AR5K_BWMODE_5MHZ) - delay = delay << 2; - /* XXX: /2 on turbo ? Let's be safe - * for now */ - usleep_range(100 + delay, 100 + (2 * delay)); - } else { - usleep_range(1000, 1500); - } -} - - -/**********************\ -* RF Gain optimization * -\**********************/ - -/** - * DOC: RF Gain optimization - * - * This code is used to optimize RF gain on different environments - * (temperature mostly) based on feedback from a power detector. - * - * It's only used on RF5111 and RF5112, later RF chips seem to have - * auto adjustment on hw -notice they have a much smaller BANK 7 and - * no gain optimization ladder-. - * - * For more infos check out this patent doc - * "http://www.freepatentsonline.com/7400691.html" - * - * This paper describes power drops as seen on the receiver due to - * probe packets - * "http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues - * %20of%20Power%20Control.pdf" - * - * And this is the MadWiFi bug entry related to the above - * "http://madwifi-project.org/ticket/1659" - * with various measurements and diagrams - */ - -/** - * ath5k_hw_rfgain_opt_init() - Initialize ah_gain during attach - * @ah: The &struct ath5k_hw - */ -int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah) -{ - /* Initialize the gain optimization values */ - switch (ah->ah_radio) { - case AR5K_RF5111: - ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default; - ah->ah_gain.g_low = 20; - ah->ah_gain.g_high = 35; - ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; - break; - case AR5K_RF5112: - ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default; - ah->ah_gain.g_low = 20; - ah->ah_gain.g_high = 85; - ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; - break; - default: - return -EINVAL; - } - - return 0; -} - -/** - * ath5k_hw_request_rfgain_probe() - Request a PAPD probe packet - * @ah: The &struct ath5k_hw - * - * Schedules a gain probe check on the next transmitted packet. - * That means our next packet is going to be sent with lower - * tx power and a Peak to Average Power Detector (PAPD) will try - * to measure the gain. - * - * TODO: Force a tx packet (bypassing PCU arbitrator etc) - * just after we enable the probe so that we don't mess with - * standard traffic. - */ -static void -ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah) -{ - - /* Skip if gain calibration is inactive or - * we already handle a probe request */ - if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE) - return; - - /* Send the packet with 2dB below max power as - * patent doc suggest */ - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4, - AR5K_PHY_PAPD_PROBE_TXPOWER) | - AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); - - ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED; - -} - -/** - * ath5k_hw_rf_gainf_corr() - Calculate Gain_F measurement correction - * @ah: The &struct ath5k_hw - * - * Calculate Gain_F measurement correction - * based on the current step for RF5112 rev. 2 - */ -static u32 -ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah) -{ - u32 mix, step; - u32 *rf; - const struct ath5k_gain_opt *go; - const struct ath5k_gain_opt_step *g_step; - const struct ath5k_rf_reg *rf_regs; - - /* Only RF5112 Rev. 2 supports it */ - if ((ah->ah_radio != AR5K_RF5112) || - (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A)) - return 0; - - go = &rfgain_opt_5112; - rf_regs = rf_regs_5112a; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a); - - g_step = &go->go_step[ah->ah_gain.g_step_idx]; - - if (ah->ah_rf_banks == NULL) - return 0; - - rf = ah->ah_rf_banks; - ah->ah_gain.g_f_corr = 0; - - /* No VGA (Variable Gain Amplifier) override, skip */ - if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1) - return 0; - - /* Mix gain stepping */ - step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false); - - /* Mix gain override */ - mix = g_step->gos_param[0]; - - switch (mix) { - case 3: - ah->ah_gain.g_f_corr = step * 2; - break; - case 2: - ah->ah_gain.g_f_corr = (step - 5) * 2; - break; - case 1: - ah->ah_gain.g_f_corr = step; - break; - default: - ah->ah_gain.g_f_corr = 0; - break; - } - - return ah->ah_gain.g_f_corr; -} - -/** - * ath5k_hw_rf_check_gainf_readback() - Validate Gain_F feedback from detector - * @ah: The &struct ath5k_hw - * - * Check if current gain_F measurement is in the range of our - * power detector windows. If we get a measurement outside range - * we know it's not accurate (detectors can't measure anything outside - * their detection window) so we must ignore it. - * - * Returns true if readback was O.K. or false on failure - */ -static bool -ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) -{ - const struct ath5k_rf_reg *rf_regs; - u32 step, mix_ovr, level[4]; - u32 *rf; - - if (ah->ah_rf_banks == NULL) - return false; - - rf = ah->ah_rf_banks; - - if (ah->ah_radio == AR5K_RF5111) { - - rf_regs = rf_regs_5111; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111); - - step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP, - false); - - level[0] = 0; - level[1] = (step == 63) ? 50 : step + 4; - level[2] = (step != 63) ? 64 : level[0]; - level[3] = level[2] + 50; - - ah->ah_gain.g_high = level[3] - - (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5); - ah->ah_gain.g_low = level[0] + - (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); - } else { - - rf_regs = rf_regs_5112; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112); - - mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, - false); - - level[0] = level[2] = 0; - - if (mix_ovr == 1) { - level[1] = level[3] = 83; - } else { - level[1] = level[3] = 107; - ah->ah_gain.g_high = 55; - } - } - - return (ah->ah_gain.g_current >= level[0] && - ah->ah_gain.g_current <= level[1]) || - (ah->ah_gain.g_current >= level[2] && - ah->ah_gain.g_current <= level[3]); -} - -/** - * ath5k_hw_rf_gainf_adjust() - Perform Gain_F adjustment - * @ah: The &struct ath5k_hw - * - * Choose the right target gain based on current gain - * and RF gain optimization ladder - */ -static s8 -ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) -{ - const struct ath5k_gain_opt *go; - const struct ath5k_gain_opt_step *g_step; - int ret = 0; - - switch (ah->ah_radio) { - case AR5K_RF5111: - go = &rfgain_opt_5111; - break; - case AR5K_RF5112: - go = &rfgain_opt_5112; - break; - default: - return 0; - } - - g_step = &go->go_step[ah->ah_gain.g_step_idx]; - - if (ah->ah_gain.g_current >= ah->ah_gain.g_high) { - - /* Reached maximum */ - if (ah->ah_gain.g_step_idx == 0) - return -1; - - for (ah->ah_gain.g_target = ah->ah_gain.g_current; - ah->ah_gain.g_target >= ah->ah_gain.g_high && - ah->ah_gain.g_step_idx > 0; - g_step = &go->go_step[ah->ah_gain.g_step_idx]) - ah->ah_gain.g_target -= 2 * - (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain - - g_step->gos_gain); - - ret = 1; - goto done; - } - - if (ah->ah_gain.g_current <= ah->ah_gain.g_low) { - - /* Reached minimum */ - if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1)) - return -2; - - for (ah->ah_gain.g_target = ah->ah_gain.g_current; - ah->ah_gain.g_target <= ah->ah_gain.g_low && - ah->ah_gain.g_step_idx < go->go_steps_count - 1; - g_step = &go->go_step[ah->ah_gain.g_step_idx]) - ah->ah_gain.g_target -= 2 * - (go->go_step[++ah->ah_gain.g_step_idx].gos_gain - - g_step->gos_gain); - - ret = 2; - goto done; - } - -done: - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, - "ret %d, gain step %u, current gain %u, target gain %u\n", - ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current, - ah->ah_gain.g_target); - - return ret; -} - -/** - * ath5k_hw_gainf_calibrate() - Do a gain_F calibration - * @ah: The &struct ath5k_hw - * - * Main callback for thermal RF gain calibration engine - * Check for a new gain reading and schedule an adjustment - * if needed. - * - * Returns one of enum ath5k_rfgain codes - */ -enum ath5k_rfgain -ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) -{ - u32 data, type; - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - - if (ah->ah_rf_banks == NULL || - ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE) - return AR5K_RFGAIN_INACTIVE; - - /* No check requested, either engine is inactive - * or an adjustment is already requested */ - if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED) - goto done; - - /* Read the PAPD (Peak to Average Power Detector) - * register */ - data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE); - - /* No probe is scheduled, read gain_F measurement */ - if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) { - ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S; - type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE); - - /* If tx packet is CCK correct the gain_F measurement - * by cck ofdm gain delta */ - if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) { - if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) - ah->ah_gain.g_current += - ee->ee_cck_ofdm_gain_delta; - else - ah->ah_gain.g_current += - AR5K_GAIN_CCK_PROBE_CORR; - } - - /* Further correct gain_F measurement for - * RF5112A radios */ - if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { - ath5k_hw_rf_gainf_corr(ah); - ah->ah_gain.g_current = - ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ? - (ah->ah_gain.g_current - ah->ah_gain.g_f_corr) : - 0; - } - - /* Check if measurement is ok and if we need - * to adjust gain, schedule a gain adjustment, - * else switch back to the active state */ - if (ath5k_hw_rf_check_gainf_readback(ah) && - AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) && - ath5k_hw_rf_gainf_adjust(ah)) { - ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE; - } else { - ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; - } - } - -done: - return ah->ah_gain.g_state; -} - -/** - * ath5k_hw_rfgain_init() - Write initial RF gain settings to hw - * @ah: The &struct ath5k_hw - * @band: One of enum ieee80211_band - * - * Write initial RF gain table to set the RF sensitivity. - * - * NOTE: This one works on all RF chips and has nothing to do - * with Gain_F calibration - */ -static int -ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band) -{ - const struct ath5k_ini_rfgain *ath5k_rfg; - unsigned int i, size, index; - - switch (ah->ah_radio) { - case AR5K_RF5111: - ath5k_rfg = rfgain_5111; - size = ARRAY_SIZE(rfgain_5111); - break; - case AR5K_RF5112: - ath5k_rfg = rfgain_5112; - size = ARRAY_SIZE(rfgain_5112); - break; - case AR5K_RF2413: - ath5k_rfg = rfgain_2413; - size = ARRAY_SIZE(rfgain_2413); - break; - case AR5K_RF2316: - ath5k_rfg = rfgain_2316; - size = ARRAY_SIZE(rfgain_2316); - break; - case AR5K_RF5413: - ath5k_rfg = rfgain_5413; - size = ARRAY_SIZE(rfgain_5413); - break; - case AR5K_RF2317: - case AR5K_RF2425: - ath5k_rfg = rfgain_2425; - size = ARRAY_SIZE(rfgain_2425); - break; - default: - return -EINVAL; - } - - index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0; - - for (i = 0; i < size; i++) { - AR5K_REG_WAIT(i); - ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index], - (u32)ath5k_rfg[i].rfg_register); - } - - return 0; -} - - -/********************\ -* RF Registers setup * -\********************/ - -/** - * ath5k_hw_rfregs_init() - Initialize RF register settings - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * @mode: One of enum ath5k_driver_mode - * - * Setup RF registers by writing RF buffer on hw. For - * more infos on this, check out rfbuffer.h - */ -static int -ath5k_hw_rfregs_init(struct ath5k_hw *ah, - struct ieee80211_channel *channel, - unsigned int mode) -{ - const struct ath5k_rf_reg *rf_regs; - const struct ath5k_ini_rfbuffer *ini_rfb; - const struct ath5k_gain_opt *go = NULL; - const struct ath5k_gain_opt_step *g_step; - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u8 ee_mode = 0; - u32 *rfb; - int i, obdb = -1, bank = -1; - - switch (ah->ah_radio) { - case AR5K_RF5111: - rf_regs = rf_regs_5111; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111); - ini_rfb = rfb_5111; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111); - go = &rfgain_opt_5111; - break; - case AR5K_RF5112: - if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) { - rf_regs = rf_regs_5112a; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a); - ini_rfb = rfb_5112a; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a); - } else { - rf_regs = rf_regs_5112; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112); - ini_rfb = rfb_5112; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112); - } - go = &rfgain_opt_5112; - break; - case AR5K_RF2413: - rf_regs = rf_regs_2413; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413); - ini_rfb = rfb_2413; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413); - break; - case AR5K_RF2316: - rf_regs = rf_regs_2316; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316); - ini_rfb = rfb_2316; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316); - break; - case AR5K_RF5413: - rf_regs = rf_regs_5413; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413); - ini_rfb = rfb_5413; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413); - break; - case AR5K_RF2317: - rf_regs = rf_regs_2425; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425); - ini_rfb = rfb_2317; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317); - break; - case AR5K_RF2425: - rf_regs = rf_regs_2425; - ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425); - if (ah->ah_mac_srev < AR5K_SREV_AR2417) { - ini_rfb = rfb_2425; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425); - } else { - ini_rfb = rfb_2417; - ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417); - } - break; - default: - return -EINVAL; - } - - /* If it's the first time we set RF buffer, allocate - * ah->ah_rf_banks based on ah->ah_rf_banks_size - * we set above */ - if (ah->ah_rf_banks == NULL) { - ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size, - GFP_KERNEL); - if (ah->ah_rf_banks == NULL) { - ATH5K_ERR(ah, "out of memory\n"); - return -ENOMEM; - } - } - - /* Copy values to modify them */ - rfb = ah->ah_rf_banks; - - for (i = 0; i < ah->ah_rf_banks_size; i++) { - if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) { - ATH5K_ERR(ah, "invalid bank\n"); - return -EINVAL; - } - - /* Bank changed, write down the offset */ - if (bank != ini_rfb[i].rfb_bank) { - bank = ini_rfb[i].rfb_bank; - ah->ah_offset[bank] = i; - } - - rfb[i] = ini_rfb[i].rfb_mode_data[mode]; - } - - /* Set Output and Driver bias current (OB/DB) */ - if (channel->band == IEEE80211_BAND_2GHZ) { - - if (channel->hw_value == AR5K_MODE_11B) - ee_mode = AR5K_EEPROM_MODE_11B; - else - ee_mode = AR5K_EEPROM_MODE_11G; - - /* For RF511X/RF211X combination we - * use b_OB and b_DB parameters stored - * in eeprom on ee->ee_ob[ee_mode][0] - * - * For all other chips we use OB/DB for 2GHz - * stored in the b/g modal section just like - * 802.11a on ee->ee_ob[ee_mode][1] */ - if ((ah->ah_radio == AR5K_RF5111) || - (ah->ah_radio == AR5K_RF5112)) - obdb = 0; - else - obdb = 1; - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb], - AR5K_RF_OB_2GHZ, true); - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb], - AR5K_RF_DB_2GHZ, true); - - /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */ - } else if ((channel->band == IEEE80211_BAND_5GHZ) || - (ah->ah_radio == AR5K_RF5111)) { - - /* For 11a, Turbo and XR we need to choose - * OB/DB based on frequency range */ - ee_mode = AR5K_EEPROM_MODE_11A; - obdb = channel->center_freq >= 5725 ? 3 : - (channel->center_freq >= 5500 ? 2 : - (channel->center_freq >= 5260 ? 1 : - (channel->center_freq > 4000 ? 0 : -1))); - - if (obdb < 0) - return -EINVAL; - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb], - AR5K_RF_OB_5GHZ, true); - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb], - AR5K_RF_DB_5GHZ, true); - } - - g_step = &go->go_step[ah->ah_gain.g_step_idx]; - - /* Set turbo mode (N/A on RF5413) */ - if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) && - (ah->ah_radio != AR5K_RF5413)) - ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false); - - /* Bank Modifications (chip-specific) */ - if (ah->ah_radio == AR5K_RF5111) { - - /* Set gain_F settings according to current step */ - if (channel->hw_value != AR5K_MODE_11B) { - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, - AR5K_PHY_FRAME_CTL_TX_CLIP, - g_step->gos_param[0]); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1], - AR5K_RF_PWD_90, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2], - AR5K_RF_PWD_84, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3], - AR5K_RF_RFGAIN_SEL, true); - - /* We programmed gain_F parameters, switch back - * to active state */ - ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; - - } - - /* Bank 6/7 setup */ - - ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode], - AR5K_RF_PWD_XPD, true); - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode], - AR5K_RF_XPD_GAIN, true); - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], - AR5K_RF_GAIN_I, true); - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], - AR5K_RF_PLO_SEL, true); - - /* Tweak power detectors for half/quarter rate support */ - if (ah->ah_bwmode == AR5K_BWMODE_5MHZ || - ah->ah_bwmode == AR5K_BWMODE_10MHZ) { - u8 wait_i; - - ath5k_hw_rfb_op(ah, rf_regs, 0x1f, - AR5K_RF_WAIT_S, true); - - wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ? - 0x1f : 0x10; - - ath5k_hw_rfb_op(ah, rf_regs, wait_i, - AR5K_RF_WAIT_I, true); - ath5k_hw_rfb_op(ah, rf_regs, 3, - AR5K_RF_MAX_TIME, true); - - } - } - - if (ah->ah_radio == AR5K_RF5112) { - - /* Set gain_F settings according to current step */ - if (channel->hw_value != AR5K_MODE_11B) { - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0], - AR5K_RF_MIXGAIN_OVR, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1], - AR5K_RF_PWD_138, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2], - AR5K_RF_PWD_137, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3], - AR5K_RF_PWD_136, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4], - AR5K_RF_PWD_132, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5], - AR5K_RF_PWD_131, true); - - ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6], - AR5K_RF_PWD_130, true); - - /* We programmed gain_F parameters, switch back - * to active state */ - ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE; - } - - /* Bank 6/7 setup */ - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode], - AR5K_RF_XPD_SEL, true); - - if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) { - /* Rev. 1 supports only one xpd */ - ath5k_hw_rfb_op(ah, rf_regs, - ee->ee_x_gain[ee_mode], - AR5K_RF_XPD_GAIN, true); - - } else { - u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode]; - if (ee->ee_pd_gains[ee_mode] > 1) { - ath5k_hw_rfb_op(ah, rf_regs, - pdg_curve_to_idx[0], - AR5K_RF_PD_GAIN_LO, true); - ath5k_hw_rfb_op(ah, rf_regs, - pdg_curve_to_idx[1], - AR5K_RF_PD_GAIN_HI, true); - } else { - ath5k_hw_rfb_op(ah, rf_regs, - pdg_curve_to_idx[0], - AR5K_RF_PD_GAIN_LO, true); - ath5k_hw_rfb_op(ah, rf_regs, - pdg_curve_to_idx[0], - AR5K_RF_PD_GAIN_HI, true); - } - - /* Lower synth voltage on Rev 2 */ - if (ah->ah_radio == AR5K_RF5112 && - (ah->ah_radio_5ghz_revision & AR5K_SREV_REV) > 0) { - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_HIGH_VC_CP, true); - - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_MID_VC_CP, true); - - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_LOW_VC_CP, true); - - ath5k_hw_rfb_op(ah, rf_regs, 2, - AR5K_RF_PUSH_UP, true); - } - - /* Decrease power consumption on 5213+ BaseBand */ - if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { - ath5k_hw_rfb_op(ah, rf_regs, 1, - AR5K_RF_PAD2GND, true); - - ath5k_hw_rfb_op(ah, rf_regs, 1, - AR5K_RF_XB2_LVL, true); - - ath5k_hw_rfb_op(ah, rf_regs, 1, - AR5K_RF_XB5_LVL, true); - - ath5k_hw_rfb_op(ah, rf_regs, 1, - AR5K_RF_PWD_167, true); - - ath5k_hw_rfb_op(ah, rf_regs, 1, - AR5K_RF_PWD_166, true); - } - } - - ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode], - AR5K_RF_GAIN_I, true); - - /* Tweak power detector for half/quarter rates */ - if (ah->ah_bwmode == AR5K_BWMODE_5MHZ || - ah->ah_bwmode == AR5K_BWMODE_10MHZ) { - u8 pd_delay; - - pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ? - 0xf : 0x8; - - ath5k_hw_rfb_op(ah, rf_regs, pd_delay, - AR5K_RF_PD_PERIOD_A, true); - ath5k_hw_rfb_op(ah, rf_regs, 0xf, - AR5K_RF_PD_DELAY_A, true); - - } - } - - if (ah->ah_radio == AR5K_RF5413 && - channel->band == IEEE80211_BAND_2GHZ) { - - ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE, - true); - - /* Set optimum value for early revisions (on pci-e chips) */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5424 && - ah->ah_mac_srev < AR5K_SREV_AR5413) - ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3), - AR5K_RF_PWD_ICLOBUF_2G, true); - - } - - /* Write RF banks on hw */ - for (i = 0; i < ah->ah_rf_banks_size; i++) { - AR5K_REG_WAIT(i); - ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register); - } - - return 0; -} - - -/**************************\ - PHY/RF channel functions -\**************************/ - -/** - * ath5k_hw_rf5110_chan2athchan() - Convert channel freq on RF5110 - * @channel: The &struct ieee80211_channel - * - * Map channel frequency to IEEE channel number and convert it - * to an internal channel value used by the RF5110 chipset. - */ -static u32 -ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) -{ - u32 athchan; - - athchan = (ath5k_hw_bitswap( - (ieee80211_frequency_to_channel( - channel->center_freq) - 24) / 2, 5) - << 1) | (1 << 6) | 0x1; - return athchan; -} - -/** - * ath5k_hw_rf5110_channel() - Set channel frequency on RF5110 - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - */ -static int -ath5k_hw_rf5110_channel(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - u32 data; - - /* - * Set the channel and wait - */ - data = ath5k_hw_rf5110_chan2athchan(channel); - ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER); - ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0); - usleep_range(1000, 1500); - - return 0; -} - -/** - * ath5k_hw_rf5111_chan2athchan() - Handle 2GHz channels on RF5111/2111 - * @ieee: IEEE channel number - * @athchan: The &struct ath5k_athchan_2ghz - * - * In order to enable the RF2111 frequency converter on RF5111/2111 setups - * we need to add some offsets and extra flags to the data values we pass - * on to the PHY. So for every 2GHz channel this function gets called - * to do the conversion. - */ -static int -ath5k_hw_rf5111_chan2athchan(unsigned int ieee, - struct ath5k_athchan_2ghz *athchan) -{ - int channel; - - /* Cast this value to catch negative channel numbers (>= -19) */ - channel = (int)ieee; - - /* - * Map 2GHz IEEE channel to 5GHz Atheros channel - */ - if (channel <= 13) { - athchan->a2_athchan = 115 + channel; - athchan->a2_flags = 0x46; - } else if (channel == 14) { - athchan->a2_athchan = 124; - athchan->a2_flags = 0x44; - } else if (channel >= 15 && channel <= 26) { - athchan->a2_athchan = ((channel - 14) * 4) + 132; - athchan->a2_flags = 0x46; - } else - return -EINVAL; - - return 0; -} - -/** - * ath5k_hw_rf5111_channel() - Set channel frequency on RF5111/2111 - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - */ -static int -ath5k_hw_rf5111_channel(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - struct ath5k_athchan_2ghz ath5k_channel_2ghz; - unsigned int ath5k_channel = - ieee80211_frequency_to_channel(channel->center_freq); - u32 data0, data1, clock; - int ret; - - /* - * Set the channel on the RF5111 radio - */ - data0 = data1 = 0; - - if (channel->band == IEEE80211_BAND_2GHZ) { - /* Map 2GHz channel to 5GHz Atheros channel ID */ - ret = ath5k_hw_rf5111_chan2athchan( - ieee80211_frequency_to_channel(channel->center_freq), - &ath5k_channel_2ghz); - if (ret) - return ret; - - ath5k_channel = ath5k_channel_2ghz.a2_athchan; - data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff) - << 5) | (1 << 4); - } - - if (ath5k_channel < 145 || !(ath5k_channel & 1)) { - clock = 1; - data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) | - (clock << 1) | (1 << 10) | 1; - } else { - clock = 0; - data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff) - << 2) | (clock << 1) | (1 << 10) | 1; - } - - ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8), - AR5K_RF_BUFFER); - ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00), - AR5K_RF_BUFFER_CONTROL_3); - - return 0; -} - -/** - * ath5k_hw_rf5112_channel() - Set channel frequency on 5112 and newer - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * On RF5112/2112 and newer we don't need to do any conversion. - * We pass the frequency value after a few modifications to the - * chip directly. - * - * NOTE: Make sure channel frequency given is within our range or else - * we might damage the chip ! Use ath5k_channel_ok before calling this one. - */ -static int -ath5k_hw_rf5112_channel(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - u32 data, data0, data1, data2; - u16 c; - - data = data0 = data1 = data2 = 0; - c = channel->center_freq; - - /* My guess based on code: - * 2GHz RF has 2 synth modes, one with a Local Oscillator - * at 2224Hz and one with a LO at 2192Hz. IF is 1520Hz - * (3040/2). data0 is used to set the PLL divider and data1 - * selects synth mode. */ - if (c < 4800) { - /* Channel 14 and all frequencies with 2Hz spacing - * below/above (non-standard channels) */ - if (!((c - 2224) % 5)) { - /* Same as (c - 2224) / 5 */ - data0 = ((2 * (c - 704)) - 3040) / 10; - data1 = 1; - /* Channel 1 and all frequencies with 5Hz spacing - * below/above (standard channels without channel 14) */ - } else if (!((c - 2192) % 5)) { - /* Same as (c - 2192) / 5 */ - data0 = ((2 * (c - 672)) - 3040) / 10; - data1 = 0; - } else - return -EINVAL; - - data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8); - /* This is more complex, we have a single synthesizer with - * 4 reference clock settings (?) based on frequency spacing - * and set using data2. LO is at 4800Hz and data0 is again used - * to set some divider. - * - * NOTE: There is an old atheros presentation at Stanford - * that mentions a method called dual direct conversion - * with 1GHz sliding IF for RF5110. Maybe that's what we - * have here, or an updated version. */ - } else if ((c % 5) != 2 || c > 5435) { - if (!(c % 20) && c >= 5120) { - data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); - data2 = ath5k_hw_bitswap(3, 2); - } else if (!(c % 10)) { - data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8); - data2 = ath5k_hw_bitswap(2, 2); - } else if (!(c % 5)) { - data0 = ath5k_hw_bitswap((c - 4800) / 5, 8); - data2 = ath5k_hw_bitswap(1, 2); - } else - return -EINVAL; - } else { - data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8); - data2 = ath5k_hw_bitswap(0, 2); - } - - data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001; - - ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER); - ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5); - - return 0; -} - -/** - * ath5k_hw_rf2425_channel() - Set channel frequency on RF2425 - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * AR2425/2417 have a different 2GHz RF so code changes - * a little bit from RF5112. - */ -static int -ath5k_hw_rf2425_channel(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - u32 data, data0, data2; - u16 c; - - data = data0 = data2 = 0; - c = channel->center_freq; - - if (c < 4800) { - data0 = ath5k_hw_bitswap((c - 2272), 8); - data2 = 0; - /* ? 5GHz ? */ - } else if ((c % 5) != 2 || c > 5435) { - if (!(c % 20) && c < 5120) - data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); - else if (!(c % 10)) - data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8); - else if (!(c % 5)) - data0 = ath5k_hw_bitswap((c - 4800) / 5, 8); - else - return -EINVAL; - data2 = ath5k_hw_bitswap(1, 2); - } else { - data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8); - data2 = ath5k_hw_bitswap(0, 2); - } - - data = (data0 << 4) | data2 << 2 | 0x1001; - - ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER); - ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5); - - return 0; -} - -/** - * ath5k_hw_channel() - Set a channel on the radio chip - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * This is the main function called to set a channel on the - * radio chip based on the radio chip version. - */ -static int -ath5k_hw_channel(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - int ret; - /* - * Check bounds supported by the PHY (we don't care about regulatory - * restrictions at this point). - */ - if (!ath5k_channel_ok(ah, channel)) { - ATH5K_ERR(ah, - "channel frequency (%u MHz) out of supported " - "band range\n", - channel->center_freq); - return -EINVAL; - } - - /* - * Set the channel and wait - */ - switch (ah->ah_radio) { - case AR5K_RF5110: - ret = ath5k_hw_rf5110_channel(ah, channel); - break; - case AR5K_RF5111: - ret = ath5k_hw_rf5111_channel(ah, channel); - break; - case AR5K_RF2317: - case AR5K_RF2425: - ret = ath5k_hw_rf2425_channel(ah, channel); - break; - default: - ret = ath5k_hw_rf5112_channel(ah, channel); - break; - } - - if (ret) - return ret; - - /* Set JAPAN setting for channel 14 */ - if (channel->center_freq == 2484) { - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL, - AR5K_PHY_CCKTXCTL_JAPAN); - } else { - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL, - AR5K_PHY_CCKTXCTL_WORLD); - } - - ah->ah_current_channel = channel; - - return 0; -} - - -/*****************\ - PHY calibration -\*****************/ - -/** - * DOC: PHY Calibration routines - * - * Noise floor calibration: When we tell the hardware to - * perform a noise floor calibration by setting the - * AR5K_PHY_AGCCTL_NF bit on AR5K_PHY_AGCCTL, it will periodically - * sample-and-hold the minimum noise level seen at the antennas. - * This value is then stored in a ring buffer of recently measured - * noise floor values so we have a moving window of the last few - * samples. The median of the values in the history is then loaded - * into the hardware for its own use for RSSI and CCA measurements. - * This type of calibration doesn't interfere with traffic. - * - * AGC calibration: When we tell the hardware to perform - * an AGC (Automatic Gain Control) calibration by setting the - * AR5K_PHY_AGCCTL_CAL, hw disconnects the antennas and does - * a calibration on the DC offsets of ADCs. During this period - * rx/tx gets disabled so we have to deal with it on the driver - * part. - * - * I/Q calibration: When we tell the hardware to perform - * an I/Q calibration, it tries to correct I/Q imbalance and - * fix QAM constellation by sampling data from rxed frames. - * It doesn't interfere with traffic. - * - * For more infos on AGC and I/Q calibration check out patent doc - * #03/094463. - */ - -/** - * ath5k_hw_read_measured_noise_floor() - Read measured NF from hw - * @ah: The &struct ath5k_hw - */ -static s32 -ath5k_hw_read_measured_noise_floor(struct ath5k_hw *ah) -{ - s32 val; - - val = ath5k_hw_reg_read(ah, AR5K_PHY_NF); - return sign_extend32(AR5K_REG_MS(val, AR5K_PHY_NF_MINCCA_PWR), 8); -} - -/** - * ath5k_hw_init_nfcal_hist() - Initialize NF calibration history buffer - * @ah: The &struct ath5k_hw - */ -void -ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah) -{ - int i; - - ah->ah_nfcal_hist.index = 0; - for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) - ah->ah_nfcal_hist.nfval[i] = AR5K_TUNE_CCA_MAX_GOOD_VALUE; -} - -/** - * ath5k_hw_update_nfcal_hist() - Update NF calibration history buffer - * @ah: The &struct ath5k_hw - * @noise_floor: The NF we got from hw - */ -static void ath5k_hw_update_nfcal_hist(struct ath5k_hw *ah, s16 noise_floor) -{ - struct ath5k_nfcal_hist *hist = &ah->ah_nfcal_hist; - hist->index = (hist->index + 1) & (ATH5K_NF_CAL_HIST_MAX - 1); - hist->nfval[hist->index] = noise_floor; -} - -/** - * ath5k_hw_get_median_noise_floor() - Get median NF from history buffer - * @ah: The &struct ath5k_hw - */ -static s16 -ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) -{ - s16 sort[ATH5K_NF_CAL_HIST_MAX]; - s16 tmp; - int i, j; - - memcpy(sort, ah->ah_nfcal_hist.nfval, sizeof(sort)); - for (i = 0; i < ATH5K_NF_CAL_HIST_MAX - 1; i++) { - for (j = 1; j < ATH5K_NF_CAL_HIST_MAX - i; j++) { - if (sort[j] > sort[j - 1]) { - tmp = sort[j]; - sort[j] = sort[j - 1]; - sort[j - 1] = tmp; - } - } - } - for (i = 0; i < ATH5K_NF_CAL_HIST_MAX; i++) { - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, - "cal %d:%d\n", i, sort[i]); - } - return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2]; -} - -/** - * ath5k_hw_update_noise_floor() - Update NF on hardware - * @ah: The &struct ath5k_hw - * - * This is the main function we call to perform a NF calibration, - * it reads NF from hardware, calculates the median and updates - * NF on hw. - */ -void -ath5k_hw_update_noise_floor(struct ath5k_hw *ah) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 val; - s16 nf, threshold; - u8 ee_mode; - - /* keep last value if calibration hasn't completed */ - if (ath5k_hw_reg_read(ah, AR5K_PHY_AGCCTL) & AR5K_PHY_AGCCTL_NF) { - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, - "NF did not complete in calibration window\n"); - - return; - } - - ah->ah_cal_mask |= AR5K_CALIBRATION_NF; - - ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); - - /* completed NF calibration, test threshold */ - nf = ath5k_hw_read_measured_noise_floor(ah); - threshold = ee->ee_noise_floor_thr[ee_mode]; - - if (nf > threshold) { - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, - "noise floor failure detected; " - "read %d, threshold %d\n", - nf, threshold); - - nf = AR5K_TUNE_CCA_MAX_GOOD_VALUE; - } - - ath5k_hw_update_nfcal_hist(ah, nf); - nf = ath5k_hw_get_median_noise_floor(ah); - - /* load noise floor (in .5 dBm) so the hardware will use it */ - val = ath5k_hw_reg_read(ah, AR5K_PHY_NF) & ~AR5K_PHY_NF_M; - val |= (nf * 2) & AR5K_PHY_NF_M; - ath5k_hw_reg_write(ah, val, AR5K_PHY_NF); - - AR5K_REG_MASKED_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF, - ~(AR5K_PHY_AGCCTL_NF_EN | AR5K_PHY_AGCCTL_NF_NOUPDATE)); - - ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_NF, - 0, false); - - /* - * Load a high max CCA Power value (-50 dBm in .5 dBm units) - * so that we're not capped by the median we just loaded. - * This will be used as the initial value for the next noise - * floor calibration. - */ - val = (val & ~AR5K_PHY_NF_M) | ((-50 * 2) & AR5K_PHY_NF_M); - ath5k_hw_reg_write(ah, val, AR5K_PHY_NF); - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_NF_EN | - AR5K_PHY_AGCCTL_NF_NOUPDATE | - AR5K_PHY_AGCCTL_NF); - - ah->ah_noise_floor = nf; - - ah->ah_cal_mask &= ~AR5K_CALIBRATION_NF; - - ATH5K_DBG(ah, ATH5K_DEBUG_CALIBRATE, - "noise floor calibrated: %d\n", nf); -} - -/** - * ath5k_hw_rf5110_calibrate() - Perform a PHY calibration on RF5110 - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * Do a complete PHY calibration (AGC + NF + I/Q) on RF5110 - */ -static int -ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - u32 phy_sig, phy_agc, phy_sat, beacon; - int ret; - - if (!(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) - return 0; - - /* - * Disable beacons and RX/TX queues, wait - */ - AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, - AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); - beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); - ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); - - usleep_range(2000, 2500); - - /* - * Set the channel (with AGC turned off) - */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); - udelay(10); - ret = ath5k_hw_channel(ah, channel); - - /* - * Activate PHY and wait - */ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); - usleep_range(1000, 1500); - - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); - - if (ret) - return ret; - - /* - * Calibrate the radio chip - */ - - /* Remember normal state */ - phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG); - phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE); - phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT); - - /* Update radio registers */ - ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) | - AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG); - - ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI | - AR5K_PHY_AGCCOARSE_LO)) | - AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) | - AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE); - - ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT | - AR5K_PHY_ADCSAT_THR)) | - AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) | - AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT); - - udelay(20); - - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); - udelay(10); - ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG); - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE); - - usleep_range(1000, 1500); - - /* - * Enable calibration and wait until completion - */ - 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, 0, false); - - /* Reset to normal state */ - ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG); - ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE); - ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT); - - if (ret) { - ATH5K_ERR(ah, "calibration timeout (%uMHz)\n", - channel->center_freq); - return ret; - } - - /* - * Re-enable RX/TX and beacons - */ - AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, - AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); - ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); - - return 0; -} - -/** - * ath5k_hw_rf511x_iq_calibrate() - Perform I/Q calibration on RF5111 and newer - * @ah: The &struct ath5k_hw - */ -static int -ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah) -{ - u32 i_pwr, q_pwr; - s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd; - int i; - - /* Skip if I/Q calibration is not needed or if it's still running */ - if (!ah->ah_iq_cal_needed) - return -EINVAL; - else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE, - "I/Q calibration still running"); - return -EBUSY; - } - - /* Calibration has finished, get the results and re-run */ - - /* Work around for empty results which can apparently happen on 5212: - * Read registers up to 10 times until we get both i_pr and q_pwr */ - for (i = 0; i <= 10; i++) { - iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR); - i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I); - q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q); - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE, - "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr); - if (i_pwr && q_pwr) - break; - } - - i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; - - if (ah->ah_version == AR5K_AR5211) - q_coffd = q_pwr >> 6; - else - q_coffd = q_pwr >> 7; - - /* In case i_coffd became zero, cancel calibration - * not only it's too small, it'll also result a divide - * by zero later on. */ - if (i_coffd == 0 || q_coffd < 2) - return -ECANCELED; - - /* Protect against loss of sign bits */ - - i_coff = (-iq_corr) / i_coffd; - i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ - - if (ah->ah_version == AR5K_AR5211) - q_coff = (i_pwr / q_coffd) - 64; - else - q_coff = (i_pwr / q_coffd) - 128; - q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ - - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE, - "new I:%d Q:%d (i_coffd:%x q_coffd:%x)", - i_coff, q_coff, i_coffd, q_coffd); - - /* Commit new I/Q values (set enable bit last to match HAL sources) */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, i_coff); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, q_coff); - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); - - /* Re-enable calibration -if we don't we'll commit - * the same values again and again */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN); - - return 0; -} - -/** - * ath5k_hw_phy_calibrate() - Perform a PHY calibration - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * The main function we call from above to perform - * a short or full PHY calibration based on RF chip - * and current channel - */ -int -ath5k_hw_phy_calibrate(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - int ret; - - if (ah->ah_radio == AR5K_RF5110) - return ath5k_hw_rf5110_calibrate(ah, channel); - - ret = ath5k_hw_rf511x_iq_calibrate(ah); - if (ret) { - ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_CALIBRATE, - "No I/Q correction performed (%uMHz)\n", - channel->center_freq); - - /* Happens all the time if there is not much - * traffic, consider it normal behaviour. */ - ret = 0; - } - - /* 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); - - return ret; -} - - -/***************************\ -* Spur mitigation functions * -\***************************/ - -/** - * ath5k_hw_set_spur_mitigation_filter() - Configure SPUR filter - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * This function gets called during PHY initialization to - * configure the spur filter for the given channel. Spur is noise - * generated due to "reflection" effects, for more information on this - * method check out patent US7643810 - */ -static void -ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 mag_mask[4] = {0, 0, 0, 0}; - u32 pilot_mask[2] = {0, 0}; - /* Note: fbin values are scaled up by 2 */ - u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window; - s32 spur_delta_phase, spur_freq_sigma_delta; - s32 spur_offset, num_symbols_x16; - u8 num_symbol_offsets, i, freq_band; - - /* Convert current frequency to fbin value (the same way channels - * are stored on EEPROM, check out ath5k_eeprom_bin2freq) and scale - * up by 2 so we can compare it later */ - if (channel->band == IEEE80211_BAND_2GHZ) { - chan_fbin = (channel->center_freq - 2300) * 10; - freq_band = AR5K_EEPROM_BAND_2GHZ; - } else { - chan_fbin = (channel->center_freq - 4900) * 10; - freq_band = AR5K_EEPROM_BAND_5GHZ; - } - - /* Check if any spur_chan_fbin from EEPROM is - * within our current channel's spur detection range */ - spur_chan_fbin = AR5K_EEPROM_NO_SPUR; - spur_detection_window = AR5K_SPUR_CHAN_WIDTH; - /* XXX: Half/Quarter channels ?*/ - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) - spur_detection_window *= 2; - - for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) { - spur_chan_fbin = ee->ee_spur_chans[i][freq_band]; - - /* Note: mask cleans AR5K_EEPROM_NO_SPUR flag - * so it's zero if we got nothing from EEPROM */ - if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) { - spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK; - break; - } - - if ((chan_fbin - spur_detection_window <= - (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) && - (chan_fbin + spur_detection_window >= - (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) { - spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK; - break; - } - } - - /* We need to enable spur filter for this channel */ - if (spur_chan_fbin) { - spur_offset = spur_chan_fbin - chan_fbin; - /* - * Calculate deltas: - * spur_freq_sigma_delta -> spur_offset / sample_freq << 21 - * spur_delta_phase -> spur_offset / chip_freq << 11 - * Note: Both values have 100Hz resolution - */ - switch (ah->ah_bwmode) { - case AR5K_BWMODE_40MHZ: - /* Both sample_freq and chip_freq are 80MHz */ - spur_delta_phase = (spur_offset << 16) / 25; - spur_freq_sigma_delta = (spur_delta_phase >> 10); - symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2; - break; - case AR5K_BWMODE_10MHZ: - /* Both sample_freq and chip_freq are 20MHz (?) */ - spur_delta_phase = (spur_offset << 18) / 25; - spur_freq_sigma_delta = (spur_delta_phase >> 10); - symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2; - case AR5K_BWMODE_5MHZ: - /* Both sample_freq and chip_freq are 10MHz (?) */ - spur_delta_phase = (spur_offset << 19) / 25; - spur_freq_sigma_delta = (spur_delta_phase >> 10); - symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4; - default: - if (channel->band == IEEE80211_BAND_5GHZ) { - /* Both sample_freq and chip_freq are 40MHz */ - spur_delta_phase = (spur_offset << 17) / 25; - spur_freq_sigma_delta = - (spur_delta_phase >> 10); - symbol_width = - AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; - } else { - /* sample_freq -> 40MHz chip_freq -> 44MHz - * (for b compatibility) */ - spur_delta_phase = (spur_offset << 17) / 25; - spur_freq_sigma_delta = - (spur_offset << 8) / 55; - symbol_width = - AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz; - } - break; - } - - /* Calculate pilot and magnitude masks */ - - /* Scale up spur_offset by 1000 to switch to 100HZ resolution - * and divide by symbol_width to find how many symbols we have - * Note: number of symbols is scaled up by 16 */ - num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width; - - /* Spur is on a symbol if num_symbols_x16 % 16 is zero */ - if (!(num_symbols_x16 & 0xF)) - /* _X_ */ - num_symbol_offsets = 3; - else - /* _xx_ */ - num_symbol_offsets = 4; - - for (i = 0; i < num_symbol_offsets; i++) { - - /* Calculate pilot mask */ - s32 curr_sym_off = - (num_symbols_x16 / 16) + i + 25; - - /* Pilot magnitude mask seems to be a way to - * declare the boundaries for our detection - * window or something, it's 2 for the middle - * value(s) where the symbol is expected to be - * and 1 on the boundary values */ - u8 plt_mag_map = - (i == 0 || i == (num_symbol_offsets - 1)) - ? 1 : 2; - - if (curr_sym_off >= 0 && curr_sym_off <= 32) { - if (curr_sym_off <= 25) - pilot_mask[0] |= 1 << curr_sym_off; - else if (curr_sym_off >= 27) - pilot_mask[0] |= 1 << (curr_sym_off - 1); - } else if (curr_sym_off >= 33 && curr_sym_off <= 52) - pilot_mask[1] |= 1 << (curr_sym_off - 33); - - /* Calculate magnitude mask (for viterbi decoder) */ - if (curr_sym_off >= -1 && curr_sym_off <= 14) - mag_mask[0] |= - plt_mag_map << (curr_sym_off + 1) * 2; - else if (curr_sym_off >= 15 && curr_sym_off <= 30) - mag_mask[1] |= - plt_mag_map << (curr_sym_off - 15) * 2; - else if (curr_sym_off >= 31 && curr_sym_off <= 46) - mag_mask[2] |= - plt_mag_map << (curr_sym_off - 31) * 2; - else if (curr_sym_off >= 47 && curr_sym_off <= 53) - mag_mask[3] |= - plt_mag_map << (curr_sym_off - 47) * 2; - - } - - /* Write settings on hw to enable spur filter */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL, - AR5K_PHY_BIN_MASK_CTL_RATE, 0xff); - /* XXX: Self correlator also ? */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_PILOT_MASK_EN | - AR5K_PHY_IQ_CHAN_MASK_EN | - AR5K_PHY_IQ_SPUR_FILT_EN); - - /* Set delta phase and freq sigma delta */ - ath5k_hw_reg_write(ah, - AR5K_REG_SM(spur_delta_phase, - AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) | - AR5K_REG_SM(spur_freq_sigma_delta, - AR5K_PHY_TIMING_11_SPUR_FREQ_SD) | - AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC, - AR5K_PHY_TIMING_11); - - /* Write pilot masks */ - ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8, - AR5K_PHY_TIMING_8_PILOT_MASK_2, - pilot_mask[1]); - - ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10, - AR5K_PHY_TIMING_10_PILOT_MASK_2, - pilot_mask[1]); - - /* Write magnitude masks */ - ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1); - ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2); - ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL, - AR5K_PHY_BIN_MASK_CTL_MASK_4, - mag_mask[3]); - - ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1); - ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2); - ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4, - AR5K_PHY_BIN_MASK2_4_MASK_4, - mag_mask[3]); - - } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & - AR5K_PHY_IQ_SPUR_FILT_EN) { - /* Clean up spur mitigation settings and disable filter */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL, - AR5K_PHY_BIN_MASK_CTL_RATE, 0); - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_PILOT_MASK_EN | - AR5K_PHY_IQ_CHAN_MASK_EN | - AR5K_PHY_IQ_SPUR_FILT_EN); - ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11); - - /* Clear pilot masks */ - ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8, - AR5K_PHY_TIMING_8_PILOT_MASK_2, - 0); - - ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10, - AR5K_PHY_TIMING_10_PILOT_MASK_2, - 0); - - /* Clear magnitude masks */ - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1); - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2); - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL, - AR5K_PHY_BIN_MASK_CTL_MASK_4, - 0); - - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1); - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2); - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4, - AR5K_PHY_BIN_MASK2_4_MASK_4, - 0); - } -} - - -/*****************\ -* Antenna control * -\*****************/ - -/** - * DOC: Antenna control - * - * Hw supports up to 14 antennas ! I haven't found any card that implements - * that. The maximum number of antennas I've seen is up to 4 (2 for 2GHz and 2 - * for 5GHz). Antenna 1 (MAIN) should be omnidirectional, 2 (AUX) - * omnidirectional or sectorial and antennas 3-14 sectorial (or directional). - * - * We can have a single antenna for RX and multiple antennas for TX. - * RX antenna is our "default" antenna (usually antenna 1) set on - * DEFAULT_ANTENNA register and TX antenna is set on each TX control descriptor - * (0 for automatic selection, 1 - 14 antenna number). - * - * We can let hw do all the work doing fast antenna diversity for both - * tx and rx or we can do things manually. Here are the options we have - * (all are bits of STA_ID1 register): - * - * AR5K_STA_ID1_DEFAULT_ANTENNA -> When 0 is set as the TX antenna on TX - * control descriptor, use the default antenna to transmit or else use the last - * antenna on which we received an ACK. - * - * AR5K_STA_ID1_DESC_ANTENNA -> Update default antenna after each TX frame to - * the antenna on which we got the ACK for that frame. - * - * AR5K_STA_ID1_RTS_DEF_ANTENNA -> Use default antenna for RTS or else use the - * one on the TX descriptor. - * - * AR5K_STA_ID1_SELFGEN_DEF_ANT -> Use default antenna for self generated frames - * (ACKs etc), or else use current antenna (the one we just used for TX). - * - * Using the above we support the following scenarios: - * - * AR5K_ANTMODE_DEFAULT -> Hw handles antenna diversity etc automatically - * - * AR5K_ANTMODE_FIXED_A -> Only antenna A (MAIN) is present - * - * AR5K_ANTMODE_FIXED_B -> Only antenna B (AUX) is present - * - * AR5K_ANTMODE_SINGLE_AP -> Sta locked on a single ap - * - * AR5K_ANTMODE_SECTOR_AP -> AP with tx antenna set on tx desc - * - * AR5K_ANTMODE_SECTOR_STA -> STA with tx antenna set on tx desc - * - * AR5K_ANTMODE_DEBUG Debug mode -A -> Rx, B-> Tx- - * - * Also note that when setting antenna to F on tx descriptor card inverts - * current tx antenna. - */ - -/** - * ath5k_hw_set_def_antenna() - Set default rx antenna on AR5211/5212 and newer - * @ah: The &struct ath5k_hw - * @ant: Antenna number - */ -static void -ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) -{ - if (ah->ah_version != AR5K_AR5210) - ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); -} - -/** - * ath5k_hw_set_fast_div() - Enable/disable fast rx antenna diversity - * @ah: The &struct ath5k_hw - * @ee_mode: One of enum ath5k_driver_mode - * @enable: True to enable, false to disable - */ -static void -ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable) -{ - switch (ee_mode) { - case AR5K_EEPROM_MODE_11G: - /* XXX: This is set to - * disabled on initvals !!! */ - case AR5K_EEPROM_MODE_11A: - if (enable) - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_OFDM_DIV_DIS); - else - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_OFDM_DIV_DIS); - break; - case AR5K_EEPROM_MODE_11B: - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_OFDM_DIV_DIS); - break; - default: - return; - } - - if (enable) { - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, - AR5K_PHY_RESTART_DIV_GC, 4); - - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, - AR5K_PHY_FAST_ANT_DIV_EN); - } else { - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART, - AR5K_PHY_RESTART_DIV_GC, 0); - - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV, - AR5K_PHY_FAST_ANT_DIV_EN); - } -} - -/** - * ath5k_hw_set_antenna_switch() - Set up antenna switch table - * @ah: The &struct ath5k_hw - * @ee_mode: One of enum ath5k_driver_mode - * - * Switch table comes from EEPROM and includes information on controlling - * the 2 antenna RX attenuators - */ -void -ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode) -{ - u8 ant0, ant1; - - /* - * In case a fixed antenna was set as default - * use the same switch table twice. - */ - if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A) - ant0 = ant1 = AR5K_ANT_SWTABLE_A; - else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B) - ant0 = ant1 = AR5K_ANT_SWTABLE_B; - else { - ant0 = AR5K_ANT_SWTABLE_A; - ant1 = AR5K_ANT_SWTABLE_B; - } - - /* Set antenna idle switch table */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, - AR5K_PHY_ANT_CTL_SWTABLE_IDLE, - (ah->ah_ant_ctl[ee_mode][AR5K_ANT_CTL] | - AR5K_PHY_ANT_CTL_TXRX_EN)); - - /* Set antenna switch tables */ - ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant0], - AR5K_PHY_ANT_SWITCH_TABLE_0); - ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant1], - AR5K_PHY_ANT_SWITCH_TABLE_1); -} - -/** - * ath5k_hw_set_antenna_mode() - Set antenna operating mode - * @ah: The &struct ath5k_hw - * @ant_mode: One of enum ath5k_ant_mode - */ -void -ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div; - bool use_def_for_sg; - int ee_mode; - u8 def_ant, tx_ant; - u32 sta_id1 = 0; - - /* if channel is not initialized yet we can't set the antennas - * so just store the mode. it will be set on the next reset */ - if (channel == NULL) { - ah->ah_ant_mode = ant_mode; - return; - } - - def_ant = ah->ah_def_ant; - - ee_mode = ath5k_eeprom_mode_from_channel(channel); - if (ee_mode < 0) { - ATH5K_ERR(ah, - "invalid channel: %d\n", channel->center_freq); - return; - } - - switch (ant_mode) { - case AR5K_ANTMODE_DEFAULT: - tx_ant = 0; - use_def_for_tx = false; - update_def_on_tx = false; - use_def_for_rts = false; - use_def_for_sg = false; - fast_div = true; - break; - case AR5K_ANTMODE_FIXED_A: - def_ant = 1; - tx_ant = 1; - use_def_for_tx = true; - update_def_on_tx = false; - use_def_for_rts = true; - use_def_for_sg = true; - fast_div = false; - break; - case AR5K_ANTMODE_FIXED_B: - def_ant = 2; - tx_ant = 2; - use_def_for_tx = true; - update_def_on_tx = false; - use_def_for_rts = true; - use_def_for_sg = true; - fast_div = false; - break; - case AR5K_ANTMODE_SINGLE_AP: - def_ant = 1; /* updated on tx */ - tx_ant = 0; - use_def_for_tx = true; - update_def_on_tx = true; - use_def_for_rts = true; - use_def_for_sg = true; - fast_div = true; - break; - case AR5K_ANTMODE_SECTOR_AP: - tx_ant = 1; /* variable */ - use_def_for_tx = false; - update_def_on_tx = false; - use_def_for_rts = true; - use_def_for_sg = false; - fast_div = false; - break; - case AR5K_ANTMODE_SECTOR_STA: - tx_ant = 1; /* variable */ - use_def_for_tx = true; - update_def_on_tx = false; - use_def_for_rts = true; - use_def_for_sg = false; - fast_div = true; - break; - case AR5K_ANTMODE_DEBUG: - def_ant = 1; - tx_ant = 2; - use_def_for_tx = false; - update_def_on_tx = false; - use_def_for_rts = false; - use_def_for_sg = false; - fast_div = false; - break; - default: - return; - } - - ah->ah_tx_ant = tx_ant; - ah->ah_ant_mode = ant_mode; - ah->ah_def_ant = def_ant; - - sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; - sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; - sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0; - sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0; - - AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS); - - if (sta_id1) - AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1); - - ath5k_hw_set_antenna_switch(ah, ee_mode); - /* Note: set diversity before default antenna - * because it won't work correctly */ - ath5k_hw_set_fast_div(ah, ee_mode, fast_div); - ath5k_hw_set_def_antenna(ah, def_ant); -} - - -/****************\ -* TX power setup * -\****************/ - -/* - * Helper functions - */ - -/** - * ath5k_get_interpolated_value() - Get interpolated Y val between two points - * @target: X value of the middle point - * @x_left: X value of the left point - * @x_right: X value of the right point - * @y_left: Y value of the left point - * @y_right: Y value of the right point - */ -static s16 -ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right, - s16 y_left, s16 y_right) -{ - s16 ratio, result; - - /* Avoid divide by zero and skip interpolation - * if we have the same point */ - if ((x_left == x_right) || (y_left == y_right)) - return y_left; - - /* - * Since we use ints and not fps, we need to scale up in - * order to get a sane ratio value (or else we 'll eg. get - * always 1 instead of 1.25, 1.75 etc). We scale up by 100 - * to have some accuracy both for 0.5 and 0.25 steps. - */ - ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left)); - - /* Now scale down to be in range */ - result = y_left + (ratio * (target - x_left) / 100); - - return result; -} - -/** - * ath5k_get_linear_pcdac_min() - Find vertical boundary (min pwr) for the - * linear PCDAC curve - * @stepL: Left array with y values (pcdac steps) - * @stepR: Right array with y values (pcdac steps) - * @pwrL: Left array with x values (power steps) - * @pwrR: Right array with x values (power steps) - * - * Since we have the top of the curve and we draw the line below - * until we reach 1 (1 pcdac step) we need to know which point - * (x value) that is so that we don't go below x axis and have negative - * pcdac values when creating the curve, or fill the table with zeros. - */ -static s16 -ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR, - const s16 *pwrL, const s16 *pwrR) -{ - s8 tmp; - s16 min_pwrL, min_pwrR; - s16 pwr_i; - - /* Some vendors write the same pcdac value twice !!! */ - if (stepL[0] == stepL[1] || stepR[0] == stepR[1]) - return max(pwrL[0], pwrR[0]); - - if (pwrL[0] == pwrL[1]) - min_pwrL = pwrL[0]; - else { - pwr_i = pwrL[0]; - do { - pwr_i--; - tmp = (s8) ath5k_get_interpolated_value(pwr_i, - pwrL[0], pwrL[1], - stepL[0], stepL[1]); - } while (tmp > 1); - - min_pwrL = pwr_i; - } - - if (pwrR[0] == pwrR[1]) - min_pwrR = pwrR[0]; - else { - pwr_i = pwrR[0]; - do { - pwr_i--; - tmp = (s8) ath5k_get_interpolated_value(pwr_i, - pwrR[0], pwrR[1], - stepR[0], stepR[1]); - } while (tmp > 1); - - min_pwrR = pwr_i; - } - - /* Keep the right boundary so that it works for both curves */ - return max(min_pwrL, min_pwrR); -} - -/** - * ath5k_create_power_curve() - Create a Power to PDADC or PCDAC curve - * @pmin: Minimum power value (xmin) - * @pmax: Maximum power value (xmax) - * @pwr: Array of power steps (x values) - * @vpd: Array of matching PCDAC/PDADC steps (y values) - * @num_points: Number of provided points - * @vpd_table: Array to fill with the full PCDAC/PDADC values (y values) - * @type: One of enum ath5k_powertable_type (eeprom.h) - * - * Interpolate (pwr,vpd) points to create a Power to PDADC or a - * Power to PCDAC curve. - * - * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC - * steps (offsets) on y axis. Power can go up to 31.5dB and max - * PCDAC/PDADC step for each curve is 64 but we can write more than - * one curves on hw so we can go up to 128 (which is the max step we - * can write on the final table). - * - * We write y values (PCDAC/PDADC steps) on hw. - */ -static void -ath5k_create_power_curve(s16 pmin, s16 pmax, - const s16 *pwr, const u8 *vpd, - u8 num_points, - u8 *vpd_table, u8 type) -{ - u8 idx[2] = { 0, 1 }; - s16 pwr_i = 2 * pmin; - int i; - - if (num_points < 2) - return; - - /* We want the whole line, so adjust boundaries - * to cover the entire power range. Note that - * power values are already 0.25dB so no need - * to multiply pwr_i by 2 */ - if (type == AR5K_PWRTABLE_LINEAR_PCDAC) { - pwr_i = pmin; - pmin = 0; - pmax = 63; - } - - /* Find surrounding turning points (TPs) - * and interpolate between them */ - for (i = 0; (i <= (u16) (pmax - pmin)) && - (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) { - - /* We passed the right TP, move to the next set of TPs - * if we pass the last TP, extrapolate above using the last - * two TPs for ratio */ - if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) { - idx[0]++; - idx[1]++; - } - - vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i, - pwr[idx[0]], pwr[idx[1]], - vpd[idx[0]], vpd[idx[1]]); - - /* Increase by 0.5dB - * (0.25 dB units) */ - pwr_i += 2; - } -} - -/** - * ath5k_get_chan_pcal_surrounding_piers() - Get surrounding calibration piers - * for a given channel. - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * @pcinfo_l: The &struct ath5k_chan_pcal_info to put the left cal. pier - * @pcinfo_r: The &struct ath5k_chan_pcal_info to put the right cal. pier - * - * Get the surrounding per-channel power calibration piers - * for a given frequency so that we can interpolate between - * them and come up with an appropriate dataset for our current - * channel. - */ -static void -ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah, - struct ieee80211_channel *channel, - struct ath5k_chan_pcal_info **pcinfo_l, - struct ath5k_chan_pcal_info **pcinfo_r) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_chan_pcal_info *pcinfo; - u8 idx_l, idx_r; - u8 mode, max, i; - u32 target = channel->center_freq; - - idx_l = 0; - idx_r = 0; - - switch (channel->hw_value) { - case AR5K_EEPROM_MODE_11A: - pcinfo = ee->ee_pwr_cal_a; - mode = AR5K_EEPROM_MODE_11A; - break; - case AR5K_EEPROM_MODE_11B: - pcinfo = ee->ee_pwr_cal_b; - mode = AR5K_EEPROM_MODE_11B; - break; - case AR5K_EEPROM_MODE_11G: - default: - pcinfo = ee->ee_pwr_cal_g; - mode = AR5K_EEPROM_MODE_11G; - break; - } - max = ee->ee_n_piers[mode] - 1; - - /* Frequency is below our calibrated - * range. Use the lowest power curve - * we have */ - if (target < pcinfo[0].freq) { - idx_l = idx_r = 0; - goto done; - } - - /* Frequency is above our calibrated - * range. Use the highest power curve - * we have */ - if (target > pcinfo[max].freq) { - idx_l = idx_r = max; - goto done; - } - - /* Frequency is inside our calibrated - * channel range. Pick the surrounding - * calibration piers so that we can - * interpolate */ - for (i = 0; i <= max; i++) { - - /* Frequency matches one of our calibration - * piers, no need to interpolate, just use - * that calibration pier */ - if (pcinfo[i].freq == target) { - idx_l = idx_r = i; - goto done; - } - - /* We found a calibration pier that's above - * frequency, use this pier and the previous - * one to interpolate */ - if (target < pcinfo[i].freq) { - idx_r = i; - idx_l = idx_r - 1; - goto done; - } - } - -done: - *pcinfo_l = &pcinfo[idx_l]; - *pcinfo_r = &pcinfo[idx_r]; -} - -/** - * ath5k_get_rate_pcal_data() - Get the interpolated per-rate power - * calibration data - * @ah: The &struct ath5k_hw *ah, - * @channel: The &struct ieee80211_channel - * @rates: The &struct ath5k_rate_pcal_info to fill - * - * Get the surrounding per-rate power calibration data - * for a given frequency and interpolate between power - * values to set max target power supported by hw for - * each rate on this frequency. - */ -static void -ath5k_get_rate_pcal_data(struct ath5k_hw *ah, - struct ieee80211_channel *channel, - struct ath5k_rate_pcal_info *rates) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_rate_pcal_info *rpinfo; - u8 idx_l, idx_r; - u8 mode, max, i; - u32 target = channel->center_freq; - - idx_l = 0; - idx_r = 0; - - switch (channel->hw_value) { - case AR5K_MODE_11A: - rpinfo = ee->ee_rate_tpwr_a; - mode = AR5K_EEPROM_MODE_11A; - break; - case AR5K_MODE_11B: - rpinfo = ee->ee_rate_tpwr_b; - mode = AR5K_EEPROM_MODE_11B; - break; - case AR5K_MODE_11G: - default: - rpinfo = ee->ee_rate_tpwr_g; - mode = AR5K_EEPROM_MODE_11G; - break; - } - max = ee->ee_rate_target_pwr_num[mode] - 1; - - /* Get the surrounding calibration - * piers - same as above */ - if (target < rpinfo[0].freq) { - idx_l = idx_r = 0; - goto done; - } - - if (target > rpinfo[max].freq) { - idx_l = idx_r = max; - goto done; - } - - for (i = 0; i <= max; i++) { - - if (rpinfo[i].freq == target) { - idx_l = idx_r = i; - goto done; - } - - if (target < rpinfo[i].freq) { - idx_r = i; - idx_l = idx_r - 1; - goto done; - } - } - -done: - /* Now interpolate power value, based on the frequency */ - rates->freq = target; - - rates->target_power_6to24 = - ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, - rpinfo[idx_r].freq, - rpinfo[idx_l].target_power_6to24, - rpinfo[idx_r].target_power_6to24); - - rates->target_power_36 = - ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, - rpinfo[idx_r].freq, - rpinfo[idx_l].target_power_36, - rpinfo[idx_r].target_power_36); - - rates->target_power_48 = - ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, - rpinfo[idx_r].freq, - rpinfo[idx_l].target_power_48, - rpinfo[idx_r].target_power_48); - - rates->target_power_54 = - ath5k_get_interpolated_value(target, rpinfo[idx_l].freq, - rpinfo[idx_r].freq, - rpinfo[idx_l].target_power_54, - rpinfo[idx_r].target_power_54); -} - -/** - * ath5k_get_max_ctl_power() - Get max edge power for a given frequency - * @ah: the &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * Get the max edge power for this channel if - * we have such data from EEPROM's Conformance Test - * Limits (CTL), and limit max power if needed. - */ -static void -ath5k_get_max_ctl_power(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - struct ath5k_edge_power *rep = ee->ee_ctl_pwr; - u8 *ctl_val = ee->ee_ctl; - s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4; - s16 edge_pwr = 0; - u8 rep_idx; - u8 i, ctl_mode; - u8 ctl_idx = 0xFF; - u32 target = channel->center_freq; - - ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band); - - switch (channel->hw_value) { - case AR5K_MODE_11A: - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) - ctl_mode |= AR5K_CTL_TURBO; - else - ctl_mode |= AR5K_CTL_11A; - break; - case AR5K_MODE_11G: - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) - ctl_mode |= AR5K_CTL_TURBOG; - else - ctl_mode |= AR5K_CTL_11G; - break; - case AR5K_MODE_11B: - ctl_mode |= AR5K_CTL_11B; - break; - default: - return; - } - - for (i = 0; i < ee->ee_ctls; i++) { - if (ctl_val[i] == ctl_mode) { - ctl_idx = i; - break; - } - } - - /* If we have a CTL dataset available grab it and find the - * edge power for our frequency */ - if (ctl_idx == 0xFF) - return; - - /* Edge powers are sorted by frequency from lower - * to higher. Each CTL corresponds to 8 edge power - * measurements. */ - rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES; - - /* Don't do boundaries check because we - * might have more that one bands defined - * for this mode */ - - /* Get the edge power that's closer to our - * frequency */ - for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) { - rep_idx += i; - if (target <= rep[rep_idx].freq) - edge_pwr = (s16) rep[rep_idx].edge; - } - - if (edge_pwr) - ah->ah_txpower.txp_max_pwr = 4 * min(edge_pwr, max_chan_pwr); -} - - -/* - * Power to PCDAC table functions - */ - -/** - * DOC: Power to PCDAC table functions - * - * For RF5111 we have an XPD -eXternal Power Detector- curve - * for each calibrated channel. Each curve has 0,5dB Power steps - * on x axis and PCDAC steps (offsets) on y axis and looks like an - * exponential function. To recreate the curve we read 11 points - * from eeprom (eeprom.c) and interpolate here. - * - * For RF5112 we have 4 XPD -eXternal Power Detector- curves - * for each calibrated channel on 0, -6, -12 and -18dBm but we only - * use the higher (3) and the lower (0) curves. Each curve again has 0.5dB - * power steps on x axis and PCDAC steps on y axis and looks like a - * linear function. To recreate the curve and pass the power values - * on hw, we get 4 points for xpd 0 (lower gain -> max power) - * and 3 points for xpd 3 (higher gain -> lower power) from eeprom (eeprom.c) - * and interpolate here. - * - * For a given channel we get the calibrated points (piers) for it or - * -if we don't have calibration data for this specific channel- from the - * available surrounding channels we have calibration data for, after we do a - * linear interpolation between them. Then since we have our calibrated points - * for this channel, we do again a linear interpolation between them to get the - * whole curve. - * - * We finally write the Y values of the curve(s) (the PCDAC values) on hw - */ - -/** - * ath5k_fill_pwr_to_pcdac_table() - Fill Power to PCDAC table on RF5111 - * @ah: The &struct ath5k_hw - * @table_min: Minimum power (x min) - * @table_max: Maximum power (x max) - * - * No further processing is needed for RF5111, the only thing we have to - * do is fill the values below and above calibration range since eeprom data - * may not cover the entire PCDAC table. - */ -static void -ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min, - s16 *table_max) -{ - u8 *pcdac_out = ah->ah_txpower.txp_pd_table; - u8 *pcdac_tmp = ah->ah_txpower.tmpL[0]; - u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx, i; - s16 min_pwr, max_pwr; - - /* Get table boundaries */ - min_pwr = table_min[0]; - pcdac_0 = pcdac_tmp[0]; - - max_pwr = table_max[0]; - pcdac_n = pcdac_tmp[table_max[0] - table_min[0]]; - - /* Extrapolate below minimum using pcdac_0 */ - pcdac_i = 0; - for (i = 0; i < min_pwr; i++) - pcdac_out[pcdac_i++] = pcdac_0; - - /* Copy values from pcdac_tmp */ - pwr_idx = min_pwr; - for (i = 0; pwr_idx <= max_pwr && - pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) { - pcdac_out[pcdac_i++] = pcdac_tmp[i]; - pwr_idx++; - } - - /* Extrapolate above maximum */ - while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE) - pcdac_out[pcdac_i++] = pcdac_n; - -} - -/** - * ath5k_combine_linear_pcdac_curves() - Combine available PCDAC Curves - * @ah: The &struct ath5k_hw - * @table_min: Minimum power (x min) - * @table_max: Maximum power (x max) - * @pdcurves: Number of pd curves - * - * Combine available XPD Curves and fill Linear Power to PCDAC table on RF5112 - * RFX112 can have up to 2 curves (one for low txpower range and one for - * higher txpower range). We need to put them both on pcdac_out and place - * them in the correct location. In case we only have one curve available - * just fit it on pcdac_out (it's supposed to cover the entire range of - * available pwr levels since it's always the higher power curve). Extrapolate - * below and above final table if needed. - */ -static void -ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, - s16 *table_max, u8 pdcurves) -{ - u8 *pcdac_out = ah->ah_txpower.txp_pd_table; - u8 *pcdac_low_pwr; - u8 *pcdac_high_pwr; - u8 *pcdac_tmp; - u8 pwr; - s16 max_pwr_idx; - s16 min_pwr_idx; - s16 mid_pwr_idx = 0; - /* Edge flag turns on the 7nth bit on the PCDAC - * to declare the higher power curve (force values - * to be greater than 64). If we only have one curve - * we don't need to set this, if we have 2 curves and - * fill the table backwards this can also be used to - * switch from higher power curve to lower power curve */ - u8 edge_flag; - int i; - - /* When we have only one curve available - * that's the higher power curve. If we have - * two curves the first is the high power curve - * and the next is the low power curve. */ - if (pdcurves > 1) { - pcdac_low_pwr = ah->ah_txpower.tmpL[1]; - pcdac_high_pwr = ah->ah_txpower.tmpL[0]; - mid_pwr_idx = table_max[1] - table_min[1] - 1; - max_pwr_idx = (table_max[0] - table_min[0]) / 2; - - /* If table size goes beyond 31.5dB, keep the - * upper 31.5dB range when setting tx power. - * Note: 126 = 31.5 dB in quarter dB steps */ - if (table_max[0] - table_min[1] > 126) - min_pwr_idx = table_max[0] - 126; - else - min_pwr_idx = table_min[1]; - - /* Since we fill table backwards - * start from high power curve */ - pcdac_tmp = pcdac_high_pwr; - - edge_flag = 0x40; - } else { - pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ - pcdac_high_pwr = ah->ah_txpower.tmpL[0]; - min_pwr_idx = table_min[0]; - max_pwr_idx = (table_max[0] - table_min[0]) / 2; - pcdac_tmp = pcdac_high_pwr; - edge_flag = 0; - } - - /* This is used when setting tx power*/ - ah->ah_txpower.txp_min_idx = min_pwr_idx / 2; - - /* Fill Power to PCDAC table backwards */ - pwr = max_pwr_idx; - for (i = 63; i >= 0; i--) { - /* Entering lower power range, reset - * edge flag and set pcdac_tmp to lower - * power curve.*/ - if (edge_flag == 0x40 && - (2 * pwr <= (table_max[1] - table_min[0]) || pwr == 0)) { - edge_flag = 0x00; - pcdac_tmp = pcdac_low_pwr; - pwr = mid_pwr_idx / 2; - } - - /* Don't go below 1, extrapolate below if we have - * already switched to the lower power curve -or - * we only have one curve and edge_flag is zero - * anyway */ - if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) { - while (i >= 0) { - pcdac_out[i] = pcdac_out[i + 1]; - i--; - } - break; - } - - pcdac_out[i] = pcdac_tmp[pwr] | edge_flag; - - /* Extrapolate above if pcdac is greater than - * 126 -this can happen because we OR pcdac_out - * value with edge_flag on high power curve */ - if (pcdac_out[i] > 126) - pcdac_out[i] = 126; - - /* Decrease by a 0.5dB step */ - pwr--; - } -} - -/** - * ath5k_write_pcdac_table() - Write the PCDAC values on hw - * @ah: The &struct ath5k_hw - */ -static void -ath5k_write_pcdac_table(struct ath5k_hw *ah) -{ - u8 *pcdac_out = ah->ah_txpower.txp_pd_table; - int i; - - /* - * Write TX power values - */ - for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { - ath5k_hw_reg_write(ah, - (((pcdac_out[2 * i + 0] << 8 | 0xff) & 0xffff) << 0) | - (((pcdac_out[2 * i + 1] << 8 | 0xff) & 0xffff) << 16), - AR5K_PHY_PCDAC_TXPOWER(i)); - } -} - - -/* - * Power to PDADC table functions - */ - -/** - * DOC: Power to PDADC table functions - * - * For RF2413 and later we have a Power to PDADC table (Power Detector) - * instead of a PCDAC (Power Control) and 4 pd gain curves for each - * calibrated channel. Each curve has power on x axis in 0.5 db steps and - * PDADC steps on y axis and looks like an exponential function like the - * RF5111 curve. - * - * To recreate the curves we read the points from eeprom (eeprom.c) - * and interpolate here. Note that in most cases only 2 (higher and lower) - * curves are used (like RF5112) but vendors have the opportunity to include - * all 4 curves on eeprom. The final curve (higher power) has an extra - * point for better accuracy like RF5112. - * - * The process is similar to what we do above for RF5111/5112 - */ - -/** - * ath5k_combine_pwr_to_pdadc_curves() - Combine the various PDADC curves - * @ah: The &struct ath5k_hw - * @pwr_min: Minimum power (x min) - * @pwr_max: Maximum power (x max) - * @pdcurves: Number of available curves - * - * Combine the various pd curves and create the final Power to PDADC table - * We can have up to 4 pd curves, we need to do a similar process - * as we do for RF5112. This time we don't have an edge_flag but we - * set the gain boundaries on a separate register. - */ -static void -ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, - s16 *pwr_min, s16 *pwr_max, u8 pdcurves) -{ - u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS]; - u8 *pdadc_out = ah->ah_txpower.txp_pd_table; - u8 *pdadc_tmp; - s16 pdadc_0; - u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size; - u8 pd_gain_overlap; - - /* Note: Register value is initialized on initvals - * there is no feedback from hw. - * XXX: What about pd_gain_overlap from EEPROM ? */ - pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) & - AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP; - - /* Create final PDADC table */ - for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) { - pdadc_tmp = ah->ah_txpower.tmpL[pdg]; - - if (pdg == pdcurves - 1) - /* 2 dB boundary stretch for last - * (higher power) curve */ - gain_boundaries[pdg] = pwr_max[pdg] + 4; - else - /* Set gain boundary in the middle - * between this curve and the next one */ - gain_boundaries[pdg] = - (pwr_max[pdg] + pwr_min[pdg + 1]) / 2; - - /* Sanity check in case our 2 db stretch got out of - * range. */ - if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER) - gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER; - - /* For the first curve (lower power) - * start from 0 dB */ - if (pdg == 0) - pdadc_0 = 0; - else - /* For the other curves use the gain overlap */ - pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) - - pd_gain_overlap; - - /* Force each power step to be at least 0.5 dB */ - if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1) - pwr_step = pdadc_tmp[1] - pdadc_tmp[0]; - else - pwr_step = 1; - - /* If pdadc_0 is negative, we need to extrapolate - * below this pdgain by a number of pwr_steps */ - while ((pdadc_0 < 0) && (pdadc_i < 128)) { - s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step; - pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp; - pdadc_0++; - } - - /* Set last pwr level, using gain boundaries */ - pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg]; - /* Limit it to be inside pwr range */ - table_size = pwr_max[pdg] - pwr_min[pdg]; - max_idx = (pdadc_n < table_size) ? pdadc_n : table_size; - - /* Fill pdadc_out table */ - while (pdadc_0 < max_idx && pdadc_i < 128) - pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++]; - - /* Need to extrapolate above this pdgain? */ - if (pdadc_n <= max_idx) - continue; - - /* Force each power step to be at least 0.5 dB */ - if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1) - pwr_step = pdadc_tmp[table_size - 1] - - pdadc_tmp[table_size - 2]; - else - pwr_step = 1; - - /* Extrapolate above */ - while ((pdadc_0 < (s16) pdadc_n) && - (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) { - s16 tmp = pdadc_tmp[table_size - 1] + - (pdadc_0 - max_idx) * pwr_step; - pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp; - pdadc_0++; - } - } - - while (pdg < AR5K_EEPROM_N_PD_GAINS) { - gain_boundaries[pdg] = gain_boundaries[pdg - 1]; - pdg++; - } - - while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) { - pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1]; - pdadc_i++; - } - - /* Set gain boundaries */ - ath5k_hw_reg_write(ah, - AR5K_REG_SM(pd_gain_overlap, - AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) | - AR5K_REG_SM(gain_boundaries[0], - AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) | - AR5K_REG_SM(gain_boundaries[1], - AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) | - AR5K_REG_SM(gain_boundaries[2], - AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) | - AR5K_REG_SM(gain_boundaries[3], - AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4), - AR5K_PHY_TPC_RG5); - - /* Used for setting rate power table */ - ah->ah_txpower.txp_min_idx = pwr_min[0]; - -} - -/** - * ath5k_write_pwr_to_pdadc_table() - Write the PDADC values on hw - * @ah: The &struct ath5k_hw - * @ee_mode: One of enum ath5k_driver_mode - */ -static void -ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u8 *pdadc_out = ah->ah_txpower.txp_pd_table; - u8 *pdg_to_idx = ee->ee_pdc_to_idx[ee_mode]; - u8 pdcurves = ee->ee_pd_gains[ee_mode]; - u32 reg; - u8 i; - - /* Select the right pdgain curves */ - - /* Clear current settings */ - reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1); - reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 | - AR5K_PHY_TPC_RG1_PDGAIN_2 | - AR5K_PHY_TPC_RG1_PDGAIN_3 | - AR5K_PHY_TPC_RG1_NUM_PD_GAIN); - - /* - * Use pd_gains curve from eeprom - * - * This overrides the default setting from initvals - * in case some vendors (e.g. Zcomax) don't use the default - * curves. If we don't honor their settings we 'll get a - * 5dB (1 * gain overlap ?) drop. - */ - reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN); - - switch (pdcurves) { - case 3: - reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3); - /* Fall through */ - case 2: - reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2); - /* Fall through */ - case 1: - reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1); - break; - } - ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1); - - /* - * Write TX power values - */ - for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) { - u32 val = get_unaligned_le32(&pdadc_out[4 * i]); - ath5k_hw_reg_write(ah, val, AR5K_PHY_PDADC_TXPOWER(i)); - } -} - - -/* - * Common code for PCDAC/PDADC tables - */ - -/** - * ath5k_setup_channel_powertable() - Set up power table for this channel - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * @ee_mode: One of enum ath5k_driver_mode - * @type: One of enum ath5k_powertable_type (eeprom.h) - * - * This is the main function that uses all of the above - * to set PCDAC/PDADC table on hw for the current channel. - * This table is used for tx power calibration on the baseband, - * without it we get weird tx power levels and in some cases - * distorted spectral mask - */ -static int -ath5k_setup_channel_powertable(struct ath5k_hw *ah, - struct ieee80211_channel *channel, - u8 ee_mode, u8 type) -{ - struct ath5k_pdgain_info *pdg_L, *pdg_R; - struct ath5k_chan_pcal_info *pcinfo_L; - struct ath5k_chan_pcal_info *pcinfo_R; - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode]; - s16 table_min[AR5K_EEPROM_N_PD_GAINS]; - s16 table_max[AR5K_EEPROM_N_PD_GAINS]; - u8 *tmpL; - u8 *tmpR; - u32 target = channel->center_freq; - int pdg, i; - - /* Get surrounding freq piers for this channel */ - ath5k_get_chan_pcal_surrounding_piers(ah, channel, - &pcinfo_L, - &pcinfo_R); - - /* Loop over pd gain curves on - * surrounding freq piers by index */ - for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) { - - /* Fill curves in reverse order - * from lower power (max gain) - * to higher power. Use curve -> idx - * backmapping we did on eeprom init */ - u8 idx = pdg_curve_to_idx[pdg]; - - /* Grab the needed curves by index */ - pdg_L = &pcinfo_L->pd_curves[idx]; - pdg_R = &pcinfo_R->pd_curves[idx]; - - /* Initialize the temp tables */ - tmpL = ah->ah_txpower.tmpL[pdg]; - tmpR = ah->ah_txpower.tmpR[pdg]; - - /* Set curve's x boundaries and create - * curves so that they cover the same - * range (if we don't do that one table - * will have values on some range and the - * other one won't have any so interpolation - * will fail) */ - table_min[pdg] = min(pdg_L->pd_pwr[0], - pdg_R->pd_pwr[0]) / 2; - - table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1], - pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2; - - /* Now create the curves on surrounding channels - * and interpolate if needed to get the final - * curve for this gain on this channel */ - switch (type) { - case AR5K_PWRTABLE_LINEAR_PCDAC: - /* Override min/max so that we don't loose - * accuracy (don't divide by 2) */ - table_min[pdg] = min(pdg_L->pd_pwr[0], - pdg_R->pd_pwr[0]); - - table_max[pdg] = - max(pdg_L->pd_pwr[pdg_L->pd_points - 1], - pdg_R->pd_pwr[pdg_R->pd_points - 1]); - - /* Override minimum so that we don't get - * out of bounds while extrapolating - * below. Don't do this when we have 2 - * curves and we are on the high power curve - * because table_min is ok in this case */ - if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) { - - table_min[pdg] = - ath5k_get_linear_pcdac_min(pdg_L->pd_step, - pdg_R->pd_step, - pdg_L->pd_pwr, - pdg_R->pd_pwr); - - /* Don't go too low because we will - * miss the upper part of the curve. - * Note: 126 = 31.5dB (max power supported) - * in 0.25dB units */ - if (table_max[pdg] - table_min[pdg] > 126) - table_min[pdg] = table_max[pdg] - 126; - } - - /* Fall through */ - case AR5K_PWRTABLE_PWR_TO_PCDAC: - case AR5K_PWRTABLE_PWR_TO_PDADC: - - ath5k_create_power_curve(table_min[pdg], - table_max[pdg], - pdg_L->pd_pwr, - pdg_L->pd_step, - pdg_L->pd_points, tmpL, type); - - /* We are in a calibration - * pier, no need to interpolate - * between freq piers */ - if (pcinfo_L == pcinfo_R) - continue; - - ath5k_create_power_curve(table_min[pdg], - table_max[pdg], - pdg_R->pd_pwr, - pdg_R->pd_step, - pdg_R->pd_points, tmpR, type); - break; - default: - return -EINVAL; - } - - /* Interpolate between curves - * of surrounding freq piers to - * get the final curve for this - * pd gain. Re-use tmpL for interpolation - * output */ - for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) && - (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) { - tmpL[i] = (u8) ath5k_get_interpolated_value(target, - (s16) pcinfo_L->freq, - (s16) pcinfo_R->freq, - (s16) tmpL[i], - (s16) tmpR[i]); - } - } - - /* Now we have a set of curves for this - * channel on tmpL (x range is table_max - table_min - * and y values are tmpL[pdg][]) sorted in the same - * order as EEPROM (because we've used the backmapping). - * So for RF5112 it's from higher power to lower power - * and for RF2413 it's from lower power to higher power. - * For RF5111 we only have one curve. */ - - /* Fill min and max power levels for this - * channel by interpolating the values on - * surrounding channels to complete the dataset */ - ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target, - (s16) pcinfo_L->freq, - (s16) pcinfo_R->freq, - pcinfo_L->min_pwr, pcinfo_R->min_pwr); - - ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target, - (s16) pcinfo_L->freq, - (s16) pcinfo_R->freq, - pcinfo_L->max_pwr, pcinfo_R->max_pwr); - - /* Fill PCDAC/PDADC table */ - switch (type) { - case AR5K_PWRTABLE_LINEAR_PCDAC: - /* For RF5112 we can have one or two curves - * and each curve covers a certain power lvl - * range so we need to do some more processing */ - ath5k_combine_linear_pcdac_curves(ah, table_min, table_max, - ee->ee_pd_gains[ee_mode]); - - /* Set txp.offset so that we can - * match max power value with max - * table index */ - ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2); - break; - case AR5K_PWRTABLE_PWR_TO_PCDAC: - /* We are done for RF5111 since it has only - * one curve, just fit the curve on the table */ - ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max); - - /* No rate powertable adjustment for RF5111 */ - ah->ah_txpower.txp_min_idx = 0; - ah->ah_txpower.txp_offset = 0; - break; - case AR5K_PWRTABLE_PWR_TO_PDADC: - /* Set PDADC boundaries and fill - * final PDADC table */ - ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max, - ee->ee_pd_gains[ee_mode]); - - /* Set txp.offset, note that table_min - * can be negative */ - ah->ah_txpower.txp_offset = table_min[0]; - break; - default: - return -EINVAL; - } - - ah->ah_txpower.txp_setup = true; - - return 0; -} - -/** - * ath5k_write_channel_powertable() - Set power table for current channel on hw - * @ah: The &struct ath5k_hw - * @ee_mode: One of enum ath5k_driver_mode - * @type: One of enum ath5k_powertable_type (eeprom.h) - */ -static void -ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type) -{ - if (type == AR5K_PWRTABLE_PWR_TO_PDADC) - ath5k_write_pwr_to_pdadc_table(ah, ee_mode); - else - ath5k_write_pcdac_table(ah); -} - - -/** - * DOC: Per-rate tx power setting - * - * This is the code that sets the desired tx power limit (below - * maximum) on hw for each rate (we also have TPC that sets - * power per packet type). We do that by providing an index on the - * PCDAC/PDADC table we set up above, for each rate. - * - * For now we only limit txpower based on maximum tx power - * supported by hw (what's inside rate_info) + conformance test - * limits. We need to limit this even more, based on regulatory domain - * etc to be safe. Normally this is done from above so we don't care - * here, all we care is that the tx power we set will be O.K. - * for the hw (e.g. won't create noise on PA etc). - * - * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps - - * x values) and is indexed as follows: - * rates[0] - rates[7] -> OFDM rates - * rates[8] - rates[14] -> CCK rates - * rates[15] -> XR rates (they all have the same power) - */ - -/** - * ath5k_setup_rate_powertable() - Set up rate power table for a given tx power - * @ah: The &struct ath5k_hw - * @max_pwr: The maximum tx power requested in 0.5dB steps - * @rate_info: The &struct ath5k_rate_pcal_info to fill - * @ee_mode: One of enum ath5k_driver_mode - */ -static void -ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, - struct ath5k_rate_pcal_info *rate_info, - u8 ee_mode) -{ - unsigned int i; - u16 *rates; - - /* max_pwr is power level we got from driver/user in 0.5dB - * units, switch to 0.25dB units so we can compare */ - max_pwr *= 2; - max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2; - - /* apply rate limits */ - rates = ah->ah_txpower.txp_rates_power_table; - - /* OFDM rates 6 to 24Mb/s */ - for (i = 0; i < 5; i++) - rates[i] = min(max_pwr, rate_info->target_power_6to24); - - /* Rest OFDM rates */ - rates[5] = min(rates[0], rate_info->target_power_36); - rates[6] = min(rates[0], rate_info->target_power_48); - rates[7] = min(rates[0], rate_info->target_power_54); - - /* CCK rates */ - /* 1L */ - rates[8] = min(rates[0], rate_info->target_power_6to24); - /* 2L */ - rates[9] = min(rates[0], rate_info->target_power_36); - /* 2S */ - rates[10] = min(rates[0], rate_info->target_power_36); - /* 5L */ - rates[11] = min(rates[0], rate_info->target_power_48); - /* 5S */ - rates[12] = min(rates[0], rate_info->target_power_48); - /* 11L */ - rates[13] = min(rates[0], rate_info->target_power_54); - /* 11S */ - rates[14] = min(rates[0], rate_info->target_power_54); - - /* XR rates */ - rates[15] = min(rates[0], rate_info->target_power_6to24); - - /* CCK rates have different peak to average ratio - * so we have to tweak their power so that gainf - * correction works ok. For this we use OFDM to - * CCK delta from eeprom */ - if ((ee_mode == AR5K_EEPROM_MODE_11G) && - (ah->ah_phy_revision < AR5K_SREV_PHY_5212A)) - for (i = 8; i <= 15; i++) - rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta; - - /* Now that we have all rates setup use table offset to - * match the power range set by user with the power indices - * on PCDAC/PDADC table */ - for (i = 0; i < 16; i++) { - rates[i] += ah->ah_txpower.txp_offset; - /* Don't get out of bounds */ - if (rates[i] > 63) - rates[i] = 63; - } - - /* Min/max in 0.25dB units */ - ah->ah_txpower.txp_min_pwr = 2 * rates[7]; - ah->ah_txpower.txp_cur_pwr = 2 * rates[0]; - ah->ah_txpower.txp_ofdm = rates[7]; -} - - -/** - * ath5k_hw_txpower() - Set transmission power limit for a given channel - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * @txpower: Requested tx power in 0.5dB steps - * - * Combines all of the above to set the requested tx power limit - * on hw. - */ -static int -ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 txpower) -{ - struct ath5k_rate_pcal_info rate_info; - struct ieee80211_channel *curr_channel = ah->ah_current_channel; - int ee_mode; - u8 type; - int ret; - - if (txpower > AR5K_TUNE_MAX_TXPOWER) { - ATH5K_ERR(ah, "invalid tx power: %u\n", txpower); - return -EINVAL; - } - - ee_mode = ath5k_eeprom_mode_from_channel(channel); - if (ee_mode < 0) { - ATH5K_ERR(ah, - "invalid channel: %d\n", channel->center_freq); - return -EINVAL; - } - - /* Initialize TX power table */ - switch (ah->ah_radio) { - case AR5K_RF5110: - /* TODO */ - return 0; - case AR5K_RF5111: - type = AR5K_PWRTABLE_PWR_TO_PCDAC; - break; - case AR5K_RF5112: - type = AR5K_PWRTABLE_LINEAR_PCDAC; - break; - case AR5K_RF2413: - case AR5K_RF5413: - case AR5K_RF2316: - case AR5K_RF2317: - case AR5K_RF2425: - type = AR5K_PWRTABLE_PWR_TO_PDADC; - break; - default: - return -EINVAL; - } - - /* - * If we don't change channel/mode skip tx powertable calculation - * and use the cached one. - */ - if (!ah->ah_txpower.txp_setup || - (channel->hw_value != curr_channel->hw_value) || - (channel->center_freq != curr_channel->center_freq)) { - /* Reset TX power values */ - memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); - ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; - - /* Calculate the powertable */ - ret = ath5k_setup_channel_powertable(ah, channel, - ee_mode, type); - if (ret) - return ret; - } - - /* Write table on hw */ - ath5k_write_channel_powertable(ah, ee_mode, type); - - /* Limit max power if we have a CTL available */ - ath5k_get_max_ctl_power(ah, channel); - - /* FIXME: Antenna reduction stuff */ - - /* FIXME: Limit power on turbo modes */ - - /* FIXME: TPC scale reduction */ - - /* Get surrounding channels for per-rate power table - * calibration */ - ath5k_get_rate_pcal_data(ah, channel, &rate_info); - - /* Setup rate power table */ - ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode); - - /* Write rate power table on hw */ - ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) | - AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) | - AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1); - - ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) | - AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) | - AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2); - - ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) | - AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) | - AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3); - - ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) | - AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) | - AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4); - - /* FIXME: TPC support */ - if (ah->ah_txpower.txp_tpc) { - ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE | - AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); - - ath5k_hw_reg_write(ah, - AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) | - AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) | - AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP), - AR5K_TPC); - } else { - ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX | - AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); - } - - return 0; -} - -/** - * ath5k_hw_set_txpower_limit() - Set txpower limit for the current channel - * @ah: The &struct ath5k_hw - * @txpower: The requested tx power limit in 0.5dB steps - * - * This function provides access to ath5k_hw_txpower to the driver in - * case user or an application changes it while PHY is running. - */ -int -ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) -{ - ATH5K_DBG(ah, ATH5K_DEBUG_TXPOWER, - "changing txpower to %d\n", txpower); - - return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower); -} - - -/*************\ - Init function -\*************/ - -/** - * ath5k_hw_phy_init() - Initialize PHY - * @ah: The &struct ath5k_hw - * @channel: The @struct ieee80211_channel - * @mode: One of enum ath5k_driver_mode - * @fast: Try a fast channel switch instead - * - * This is the main function used during reset to initialize PHY - * or do a fast channel change if possible. - * - * NOTE: Do not call this one from the driver, it assumes PHY is in a - * warm reset state ! - */ -int -ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, - u8 mode, bool fast) -{ - struct ieee80211_channel *curr_channel; - int ret, i; - u32 phy_tst1; - ret = 0; - - /* - * Sanity check for fast flag - * Don't try fast channel change when changing modulation - * mode/band. We check for chip compatibility on - * ath5k_hw_reset. - */ - curr_channel = ah->ah_current_channel; - if (fast && (channel->hw_value != curr_channel->hw_value)) - return -EINVAL; - - /* - * On fast channel change we only set the synth parameters - * while PHY is running, enable calibration and skip the rest. - */ - if (fast) { - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, - AR5K_PHY_RFBUS_REQ_REQUEST); - for (i = 0; i < 100; i++) { - if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT)) - break; - udelay(5); - } - /* Failed */ - if (i >= 100) - return -EIO; - - /* Set channel and wait for synth */ - ret = ath5k_hw_channel(ah, channel); - if (ret) - return ret; - - ath5k_hw_wait_for_synth(ah, channel); - } - - /* - * Set TX power - * - * Note: We need to do that before we set - * RF buffer settings on 5211/5212+ so that we - * properly set curve indices. - */ - ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ? - ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER); - if (ret) - return ret; - - /* Write OFDM timings on 5212*/ - if (ah->ah_version == AR5K_AR5212 && - channel->hw_value != AR5K_MODE_11B) { - - ret = ath5k_hw_write_ofdm_timings(ah, channel); - if (ret) - return ret; - - /* Spur info is available only from EEPROM versions - * greater than 5.3, but the EEPROM routines will use - * static values for older versions */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5424) - ath5k_hw_set_spur_mitigation_filter(ah, - channel); - } - - /* If we used fast channel switching - * we are done, release RF bus and - * fire up NF calibration. - * - * Note: Only NF calibration due to - * channel change, not AGC calibration - * since AGC is still running ! - */ - if (fast) { - /* - * Release RF Bus grant - */ - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ, - AR5K_PHY_RFBUS_REQ_REQUEST); - - /* - * Start NF calibration - */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_NF); - - return ret; - } - - /* - * For 5210 we do all initialization using - * initvals, so we don't have to modify - * any settings (5210 also only supports - * a/aturbo modes) - */ - if (ah->ah_version != AR5K_AR5210) { - - /* - * Write initial RF gain settings - * This should work for both 5111/5112 - */ - ret = ath5k_hw_rfgain_init(ah, channel->band); - if (ret) - return ret; - - usleep_range(1000, 1500); - - /* - * Write RF buffer - */ - ret = ath5k_hw_rfregs_init(ah, channel, mode); - if (ret) - return ret; - - /*Enable/disable 802.11b mode on 5111 - (enable 2111 frequency converter + CCK)*/ - if (ah->ah_radio == AR5K_RF5111) { - if (mode == AR5K_MODE_11B) - AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_B_MODE); - else - AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_B_MODE); - } - - } else if (ah->ah_version == AR5K_AR5210) { - usleep_range(1000, 1500); - /* Disable phy and wait */ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); - usleep_range(1000, 1500); - } - - /* Set channel on PHY */ - ret = ath5k_hw_channel(ah, channel); - if (ret) - return ret; - - /* - * Enable the PHY and wait until completion - * This includes BaseBand and Synthesizer - * activation. - */ - ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); - - ath5k_hw_wait_for_synth(ah, channel); - - /* - * Perform ADC test to see if baseband is ready - * Set tx hold and check adc test register - */ - phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); - ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); - for (i = 0; i <= 20; i++) { - if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) - break; - usleep_range(200, 250); - } - ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); - - /* - * Start automatic gain control calibration - * - * During AGC calibration RX path is re-routed to - * a power detector so we don't receive anything. - * - * This method is used to calibrate some static offsets - * used together with on-the fly I/Q calibration (the - * one performed via ath5k_hw_phy_calibrate), which doesn't - * interrupt rx path. - * - * While rx path is re-routed to the power detector we also - * start a noise floor calibration to measure the - * card's noise floor (the noise we measure when we are not - * transmitting or receiving anything). - * - * If we are in a noisy environment, AGC calibration may time - * out and/or noise floor calibration might timeout. - */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF); - - /* At the same time start I/Q calibration for QAM constellation - * -no need for CCK- */ - ah->ah_iq_cal_needed = false; - if (!(mode == AR5K_MODE_11B)) { - ah->ah_iq_cal_needed = true; - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, - AR5K_PHY_IQ_RUN); - } - - /* Wait for gain calibration to finish (we check for I/Q calibration - * during ath5k_phy_calibrate) */ - if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, - AR5K_PHY_AGCCTL_CAL, 0, false)) { - ATH5K_ERR(ah, "gain calibration timeout (%uMHz)\n", - channel->center_freq); - } - - /* Restore antenna mode */ - ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); - - return ret; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/qcu.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/qcu.c deleted file mode 100644 index 30b50f93..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/qcu.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/********************************************\ -Queue Control Unit, DCF Control Unit Functions -\********************************************/ - -#include "ath5k.h" -#include "reg.h" -#include "debug.h" -#include <linux/log2.h> - -/** - * DOC: Queue Control Unit (QCU)/DCF Control Unit (DCU) functions - * - * Here we setup parameters for the 12 available TX queues. Note that - * on the various registers we can usually only map the first 10 of them so - * basically we have 10 queues to play with. Each queue has a matching - * QCU that controls when the queue will get triggered and multiple QCUs - * can be mapped to a single DCU that controls the various DFS parameters - * for the various queues. In our setup we have a 1:1 mapping between QCUs - * and DCUs allowing us to have different DFS settings for each queue. - * - * When a frame goes into a TX queue, QCU decides when it'll trigger a - * transmission based on various criteria (such as how many data we have inside - * it's buffer or -if it's a beacon queue- if it's time to fire up the queue - * based on TSF etc), DCU adds backoff, IFSes etc and then a scheduler - * (arbitrator) decides the priority of each QCU based on it's configuration - * (e.g. beacons are always transmitted when they leave DCU bypassing all other - * frames from other queues waiting to be transmitted). After a frame leaves - * the DCU it goes to PCU for further processing and then to PHY for - * the actual transmission. - */ - - -/******************\ -* Helper functions * -\******************/ - -/** - * ath5k_hw_num_tx_pending() - Get number of pending frames for a given queue - * @ah: The &struct ath5k_hw - * @queue: One of enum ath5k_tx_queue_id - */ -u32 -ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) -{ - u32 pending; - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - /* Return if queue is declared inactive */ - if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) - return false; - - /* XXX: How about AR5K_CFG_TXCNT ? */ - if (ah->ah_version == AR5K_AR5210) - return false; - - pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)); - pending &= AR5K_QCU_STS_FRMPENDCNT; - - /* It's possible to have no frames pending even if TXE - * is set. To indicate that q has not stopped return - * true */ - if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) - return true; - - return pending; -} - -/** - * ath5k_hw_release_tx_queue() - Set a transmit queue inactive - * @ah: The &struct ath5k_hw - * @queue: One of enum ath5k_tx_queue_id - */ -void -ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) -{ - if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) - return; - - /* This queue will be skipped in further operations */ - ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; - /*For SIMR setup*/ - AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); -} - -/** - * ath5k_cw_validate() - Make sure the given cw is valid - * @cw_req: The contention window value to check - * - * Make sure cw is a power of 2 minus 1 and smaller than 1024 - */ -static u16 -ath5k_cw_validate(u16 cw_req) -{ - cw_req = min(cw_req, (u16)1023); - - /* Check if cw_req + 1 a power of 2 */ - if (is_power_of_2(cw_req + 1)) - return cw_req; - - /* Check if cw_req is a power of 2 */ - if (is_power_of_2(cw_req)) - return cw_req - 1; - - /* If none of the above is correct - * find the closest power of 2 */ - cw_req = (u16) roundup_pow_of_two(cw_req) - 1; - - return cw_req; -} - -/** - * ath5k_hw_get_tx_queueprops() - Get properties for a transmit queue - * @ah: The &struct ath5k_hw - * @queue: One of enum ath5k_tx_queue_id - * @queue_info: The &struct ath5k_txq_info to fill - */ -int -ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, - struct ath5k_txq_info *queue_info) -{ - memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); - return 0; -} - -/** - * ath5k_hw_set_tx_queueprops() - Set properties for a transmit queue - * @ah: The &struct ath5k_hw - * @queue: One of enum ath5k_tx_queue_id - * @qinfo: The &struct ath5k_txq_info to use - * - * Returns 0 on success or -EIO if queue is inactive - */ -int -ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, - const struct ath5k_txq_info *qinfo) -{ - struct ath5k_txq_info *qi; - - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - qi = &ah->ah_txq[queue]; - - if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE) - return -EIO; - - /* copy and validate values */ - qi->tqi_type = qinfo->tqi_type; - qi->tqi_subtype = qinfo->tqi_subtype; - qi->tqi_flags = qinfo->tqi_flags; - /* - * According to the docs: Although the AIFS field is 8 bit wide, - * the maximum supported value is 0xFC. Setting it higher than that - * will cause the DCU to hang. - */ - qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC); - qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min); - qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max); - qi->tqi_cbr_period = qinfo->tqi_cbr_period; - qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit; - qi->tqi_burst_time = qinfo->tqi_burst_time; - qi->tqi_ready_time = qinfo->tqi_ready_time; - - /*XXX: Is this supported on 5210 ?*/ - /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/ - if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA && - ((qinfo->tqi_subtype == AR5K_WME_AC_VI) || - (qinfo->tqi_subtype == AR5K_WME_AC_VO))) || - qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD) - qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; - - return 0; -} - -/** - * ath5k_hw_setup_tx_queue() - Initialize a transmit queue - * @ah: The &struct ath5k_hw - * @queue_type: One of enum ath5k_tx_queue - * @queue_info: The &struct ath5k_txq_info to use - * - * Returns 0 on success, -EINVAL on invalid arguments - */ -int -ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, - struct ath5k_txq_info *queue_info) -{ - unsigned int queue; - int ret; - - /* - * Get queue by type - */ - /* 5210 only has 2 queues */ - if (ah->ah_capabilities.cap_queues.q_tx_num == 2) { - switch (queue_type) { - case AR5K_TX_QUEUE_DATA: - queue = AR5K_TX_QUEUE_ID_NOQCU_DATA; - break; - case AR5K_TX_QUEUE_BEACON: - case AR5K_TX_QUEUE_CAB: - queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON; - break; - default: - return -EINVAL; - } - } else { - switch (queue_type) { - case AR5K_TX_QUEUE_DATA: - for (queue = AR5K_TX_QUEUE_ID_DATA_MIN; - ah->ah_txq[queue].tqi_type != - AR5K_TX_QUEUE_INACTIVE; queue++) { - - if (queue > AR5K_TX_QUEUE_ID_DATA_MAX) - return -EINVAL; - } - break; - case AR5K_TX_QUEUE_UAPSD: - queue = AR5K_TX_QUEUE_ID_UAPSD; - break; - case AR5K_TX_QUEUE_BEACON: - queue = AR5K_TX_QUEUE_ID_BEACON; - break; - case AR5K_TX_QUEUE_CAB: - queue = AR5K_TX_QUEUE_ID_CAB; - break; - default: - return -EINVAL; - } - } - - /* - * Setup internal queue structure - */ - memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info)); - ah->ah_txq[queue].tqi_type = queue_type; - - if (queue_info != NULL) { - queue_info->tqi_type = queue_type; - ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info); - if (ret) - return ret; - } - - /* - * We use ah_txq_status to hold a temp value for - * the Secondary interrupt mask registers on 5211+ - * check out ath5k_hw_reset_tx_queue - */ - AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue); - - return queue; -} - - -/*******************************\ -* Single QCU/DCU initialization * -\*******************************/ - -/** - * ath5k_hw_set_tx_retry_limits() - Set tx retry limits on DCU - * @ah: The &struct ath5k_hw - * @queue: One of enum ath5k_tx_queue_id - * - * This function is used when initializing a queue, to set - * retry limits based on ah->ah_retry_* and the chipset used. - */ -void -ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, - unsigned int queue) -{ - /* Single data queue on AR5210 */ - if (ah->ah_version == AR5K_AR5210) { - struct ath5k_txq_info *tq = &ah->ah_txq[queue]; - - if (queue > 0) - return; - - ath5k_hw_reg_write(ah, - (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) - | AR5K_REG_SM(ah->ah_retry_long, - AR5K_NODCU_RETRY_LMT_SLG_RETRY) - | AR5K_REG_SM(ah->ah_retry_short, - AR5K_NODCU_RETRY_LMT_SSH_RETRY) - | AR5K_REG_SM(ah->ah_retry_long, - AR5K_NODCU_RETRY_LMT_LG_RETRY) - | AR5K_REG_SM(ah->ah_retry_short, - AR5K_NODCU_RETRY_LMT_SH_RETRY), - AR5K_NODCU_RETRY_LMT); - /* DCU on AR5211+ */ - } else { - ath5k_hw_reg_write(ah, - AR5K_REG_SM(ah->ah_retry_long, - AR5K_DCU_RETRY_LMT_RTS) - | AR5K_REG_SM(ah->ah_retry_long, - AR5K_DCU_RETRY_LMT_STA_RTS) - | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short), - AR5K_DCU_RETRY_LMT_STA_DATA), - AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); - } -} - -/** - * ath5k_hw_reset_tx_queue() - Initialize a single hw queue - * @ah: The &struct ath5k_hw - * @queue: One of enum ath5k_tx_queue_id - * - * Set DCF properties for the given transmit queue on DCU - * and configures all queue-specific parameters. - */ -int -ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) -{ - struct ath5k_txq_info *tq = &ah->ah_txq[queue]; - - AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - - tq = &ah->ah_txq[queue]; - - /* Skip if queue inactive or if we are on AR5210 - * that doesn't have QCU/DCU */ - if ((ah->ah_version == AR5K_AR5210) || - (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)) - return 0; - - /* - * Set contention window (cw_min/cw_max) - * and arbitrated interframe space (aifs)... - */ - ath5k_hw_reg_write(ah, - AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | - AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | - AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), - AR5K_QUEUE_DFS_LOCAL_IFS(queue)); - - /* - * Set tx retry limits for this queue - */ - ath5k_hw_set_tx_retry_limits(ah, queue); - - - /* - * Set misc registers - */ - - /* Enable DCU to wait for next fragment from QCU */ - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - AR5K_DCU_MISC_FRAG_WAIT); - - /* On Maui and Spirit use the global seqnum on DCU */ - if (ah->ah_mac_version < AR5K_SREV_AR5211) - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - AR5K_DCU_MISC_SEQNUM_CTL); - - /* Constant bit rate period */ - if (tq->tqi_cbr_period) { - ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, - AR5K_QCU_CBRCFG_INTVAL) | - AR5K_REG_SM(tq->tqi_cbr_overflow_limit, - AR5K_QCU_CBRCFG_ORN_THRES), - AR5K_QUEUE_CBRCFG(queue)); - - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_CBR); - - if (tq->tqi_cbr_overflow_limit) - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_CBR_THRES_ENABLE); - } - - /* Ready time interval */ - if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB)) - ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, - AR5K_QCU_RDYTIMECFG_INTVAL) | - AR5K_QCU_RDYTIMECFG_ENABLE, - AR5K_QUEUE_RDYTIMECFG(queue)); - - if (tq->tqi_burst_time) { - ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, - AR5K_DCU_CHAN_TIME_DUR) | - AR5K_DCU_CHAN_TIME_ENABLE, - AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_RDY_VEOL_POLICY); - } - - /* Enable/disable Post frame backoff */ - if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) - ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, - AR5K_QUEUE_DFS_MISC(queue)); - - /* Enable/disable fragmentation burst backoff */ - if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) - ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, - AR5K_QUEUE_DFS_MISC(queue)); - - /* - * Set registers by queue type - */ - switch (tq->tqi_type) { - case AR5K_TX_QUEUE_BEACON: - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_DBA_GT | - AR5K_QCU_MISC_CBREXP_BCN_DIS | - AR5K_QCU_MISC_BCN_ENABLE); - - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << - AR5K_DCU_MISC_ARBLOCK_CTL_S) | - AR5K_DCU_MISC_ARBLOCK_IGNORE | - AR5K_DCU_MISC_POST_FR_BKOFF_DIS | - AR5K_DCU_MISC_BCN_ENABLE); - break; - - case AR5K_TX_QUEUE_CAB: - /* XXX: use BCN_SENT_GT, if we can figure out how */ - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_DBA_GT | - AR5K_QCU_MISC_CBREXP_DIS | - AR5K_QCU_MISC_CBREXP_BCN_DIS); - - ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - - (AR5K_TUNE_SW_BEACON_RESP - - AR5K_TUNE_DMA_BEACON_RESP) - - AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | - AR5K_QCU_RDYTIMECFG_ENABLE, - AR5K_QUEUE_RDYTIMECFG(queue)); - - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), - (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << - AR5K_DCU_MISC_ARBLOCK_CTL_S)); - break; - - case AR5K_TX_QUEUE_UAPSD: - AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_CBREXP_DIS); - break; - - case AR5K_TX_QUEUE_DATA: - default: - break; - } - - /* TODO: Handle frame compression */ - - /* - * Enable interrupts for this tx queue - * in the secondary interrupt mask registers - */ - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); - - if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) - AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); - - /* Update secondary interrupt mask registers */ - - /* Filter out inactive queues */ - ah->ah_txq_imr_txok &= ah->ah_txq_status; - ah->ah_txq_imr_txerr &= ah->ah_txq_status; - ah->ah_txq_imr_txurn &= ah->ah_txq_status; - ah->ah_txq_imr_txdesc &= ah->ah_txq_status; - ah->ah_txq_imr_txeol &= ah->ah_txq_status; - ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; - ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; - ah->ah_txq_imr_qtrig &= ah->ah_txq_status; - ah->ah_txq_imr_nofrm &= ah->ah_txq_status; - - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, - AR5K_SIMR0_QCU_TXOK) | - AR5K_REG_SM(ah->ah_txq_imr_txdesc, - AR5K_SIMR0_QCU_TXDESC), - AR5K_SIMR0); - - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, - AR5K_SIMR1_QCU_TXERR) | - AR5K_REG_SM(ah->ah_txq_imr_txeol, - AR5K_SIMR1_QCU_TXEOL), - AR5K_SIMR1); - - /* Update SIMR2 but don't overwrite rest simr2 settings */ - AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); - AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, - AR5K_REG_SM(ah->ah_txq_imr_txurn, - AR5K_SIMR2_QCU_TXURN)); - - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, - AR5K_SIMR3_QCBRORN) | - AR5K_REG_SM(ah->ah_txq_imr_cbrurn, - AR5K_SIMR3_QCBRURN), - AR5K_SIMR3); - - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, - AR5K_SIMR4_QTRIG), AR5K_SIMR4); - - /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ - ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, - AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); - - /* No queue has TXNOFRM enabled, disable the interrupt - * by setting AR5K_TXNOFRM to zero */ - if (ah->ah_txq_imr_nofrm == 0) - ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); - - /* Set QCU mask for this DCU to save power */ - AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); - - return 0; -} - - -/**************************\ -* Global QCU/DCU functions * -\**************************/ - -/** - * ath5k_hw_set_ifs_intervals() - Set global inter-frame spaces on DCU - * @ah: The &struct ath5k_hw - * @slot_time: Slot time in us - * - * Sets the global IFS intervals on DCU (also works on AR5210) for - * the given slot time and the current bwmode. - */ -int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - struct ieee80211_rate *rate; - u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock; - u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); - - if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) - return -EINVAL; - - sifs = ath5k_hw_get_default_sifs(ah); - sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); - - /* EIFS - * Txtime of ack at lowest rate + SIFS + DIFS - * (DIFS = SIFS + 2 * Slot time) - * - * Note: HAL has some predefined values for EIFS - * Turbo: (37 + 2 * 6) - * Default: (74 + 2 * 9) - * Half: (149 + 2 * 13) - * Quarter: (298 + 2 * 21) - * - * (74 + 2 * 6) for AR5210 default and turbo ! - * - * According to the formula we have - * ack_tx_time = 25 for turbo and - * ack_tx_time = 42.5 * clock multiplier - * for default/half/quarter. - * - * This can't be right, 42 is what we would get - * from ath5k_hw_get_frame_dur_for_bwmode or - * ieee80211_generic_frame_duration for zero frame - * length and without SIFS ! - * - * Also we have different lowest rate for 802.11a - */ - if (channel->band == IEEE80211_BAND_5GHZ) - rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0]; - else - rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; - - ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); - - /* ack_tx_time includes an SIFS already */ - eifs = ack_tx_time + sifs + 2 * slot_time; - eifs_clock = ath5k_hw_htoclock(ah, eifs); - - /* Set IFS settings on AR5210 */ - if (ah->ah_version == AR5K_AR5210) { - u32 pifs, pifs_clock, difs, difs_clock; - - /* Set slot time */ - ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); - - /* Set EIFS */ - eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS); - - /* PIFS = Slot time + SIFS */ - pifs = slot_time + sifs; - pifs_clock = ath5k_hw_htoclock(ah, pifs); - pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS); - - /* DIFS = SIFS + 2 * Slot time */ - difs = sifs + 2 * slot_time; - difs_clock = ath5k_hw_htoclock(ah, difs); - - /* Set SIFS/DIFS */ - ath5k_hw_reg_write(ah, (difs_clock << - AR5K_IFS0_DIFS_S) | sifs_clock, - AR5K_IFS0); - - /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */ - ath5k_hw_reg_write(ah, pifs_clock | eifs_clock | - (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S), - AR5K_IFS1); - - return 0; - } - - /* Set IFS slot time */ - ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); - - /* Set EIFS interval */ - ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS); - - /* Set SIFS interval in usecs */ - AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, - AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC, - sifs); - - /* Set SIFS interval in clock cycles */ - ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS); - - return 0; -} - - -/** - * ath5k_hw_init_queues() - Initialize tx queues - * @ah: The &struct ath5k_hw - * - * Initializes all tx queues based on information on - * ah->ah_txq* set by the driver - */ -int -ath5k_hw_init_queues(struct ath5k_hw *ah) -{ - int i, ret; - - /* TODO: HW Compression support for data queues */ - /* TODO: Burst prefetch for data queues */ - - /* - * Reset queues and start beacon timers at the end of the reset routine - * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping - * Note: If we want we can assign multiple qcus on one dcu. - */ - if (ah->ah_version != AR5K_AR5210) - for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { - ret = ath5k_hw_reset_tx_queue(ah, i); - if (ret) { - ATH5K_ERR(ah, - "failed to reset TX queue #%d\n", i); - return ret; - } - } - else - /* No QCU/DCU on AR5210, just set tx - * retry limits. We set IFS parameters - * on ath5k_hw_set_ifs_intervals */ - ath5k_hw_set_tx_retry_limits(ah, 0); - - /* Set the turbo flag when operating on 40MHz */ - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) - AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, - AR5K_DCU_GBL_IFS_MISC_TURBO_MODE); - - /* If we didn't set IFS timings through - * ath5k_hw_set_coverage_class make sure - * we set them here */ - if (!ah->ah_coverage_class) { - unsigned int slot_time = ath5k_hw_get_default_slottime(ah); - ath5k_hw_set_ifs_intervals(ah, slot_time); - } - - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/reg.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/reg.h deleted file mode 100644 index 0ea1608b..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/reg.h +++ /dev/null @@ -1,2604 +0,0 @@ -/* - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/* - * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k - * maintained by Reyk Floeter - * - * I tried to document those registers by looking at ar5k code, some - * 802.11 (802.11e mostly) papers and by reading various public available - * Atheros presentations and papers like these: - * - * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf - * - * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf - * - * This file also contains register values found on a memory dump of - * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal - * released by Atheros and on various debug messages found on the net. - */ - -#include "../reg.h" - -/*====MAC DMA REGISTERS====*/ - -/* - * AR5210-Specific TXDP registers - * 5210 has only 2 transmit queues so no DCU/QCU, just - * 2 transmit descriptor pointers... - */ -#define AR5K_NOQCU_TXDP0 0x0000 /* Queue 0 - data */ -#define AR5K_NOQCU_TXDP1 0x0004 /* Queue 1 - beacons */ - -/* - * Mac Control Register - */ -#define AR5K_CR 0x0008 /* Register Address */ -#define AR5K_CR_TXE0 0x00000001 /* TX Enable for queue 0 on 5210 */ -#define AR5K_CR_TXE1 0x00000002 /* TX Enable for queue 1 on 5210 */ -#define AR5K_CR_RXE 0x00000004 /* RX Enable */ -#define AR5K_CR_TXD0 0x00000008 /* TX Disable for queue 0 on 5210 */ -#define AR5K_CR_TXD1 0x00000010 /* TX Disable for queue 1 on 5210 */ -#define AR5K_CR_RXD 0x00000020 /* RX Disable */ -#define AR5K_CR_SWI 0x00000040 /* Software Interrupt */ - -/* - * RX Descriptor Pointer register - */ -#define AR5K_RXDP 0x000c - -/* - * Configuration and status register - */ -#define AR5K_CFG 0x0014 /* Register Address */ -#define AR5K_CFG_SWTD 0x00000001 /* Byte-swap TX descriptor (for big endian archs) */ -#define AR5K_CFG_SWTB 0x00000002 /* Byte-swap TX buffer */ -#define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */ -#define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */ -#define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */ -#define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ -#define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */ -#define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */ -#define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */ -#define AR5K_CFG_TXCNT 0x00007800 /* Tx frame count (?) [5210] */ -#define AR5K_CFG_TXCNT_S 11 -#define AR5K_CFG_TXFSTAT 0x00008000 /* Tx frame status (?) [5210] */ -#define AR5K_CFG_TXFSTRT 0x00010000 /* [5210] */ -#define AR5K_CFG_PCI_THRES 0x00060000 /* PCI Master req q threshold [5211+] */ -#define AR5K_CFG_PCI_THRES_S 17 - -/* - * Interrupt enable register - */ -#define AR5K_IER 0x0024 /* Register Address */ -#define AR5K_IER_DISABLE 0x00000000 /* Disable card interrupts */ -#define AR5K_IER_ENABLE 0x00000001 /* Enable card interrupts */ - - -/* - * 0x0028 is Beacon Control Register on 5210 - * and first RTS duration register on 5211 - */ - -/* - * Beacon control register [5210] - */ -#define AR5K_BCR 0x0028 /* Register Address */ -#define AR5K_BCR_AP 0x00000000 /* AP mode */ -#define AR5K_BCR_ADHOC 0x00000001 /* Ad-Hoc mode */ -#define AR5K_BCR_BDMAE 0x00000002 /* DMA enable */ -#define AR5K_BCR_TQ1FV 0x00000004 /* Use Queue1 for CAB traffic */ -#define AR5K_BCR_TQ1V 0x00000008 /* Use Queue1 for Beacon traffic */ -#define AR5K_BCR_BCGET 0x00000010 - -/* - * First RTS duration register [5211] - */ -#define AR5K_RTSD0 0x0028 /* Register Address */ -#define AR5K_RTSD0_6 0x000000ff /* 6Mb RTS duration mask (?) */ -#define AR5K_RTSD0_6_S 0 /* 6Mb RTS duration shift (?) */ -#define AR5K_RTSD0_9 0x0000ff00 /* 9Mb*/ -#define AR5K_RTSD0_9_S 8 -#define AR5K_RTSD0_12 0x00ff0000 /* 12Mb*/ -#define AR5K_RTSD0_12_S 16 -#define AR5K_RTSD0_18 0xff000000 /* 16Mb*/ -#define AR5K_RTSD0_18_S 24 - - -/* - * 0x002c is Beacon Status Register on 5210 - * and second RTS duration register on 5211 - */ - -/* - * Beacon status register [5210] - * - * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR - * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning - * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR). - * So SNAPPEDBCRVALID should also stand for "snapped BCR -values- valid", so i - * renamed it to SNAPSHOTSVALID to make more sense. I really have no idea what - * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR. - */ -#define AR5K_BSR 0x002c /* Register Address */ -#define AR5K_BSR_BDLYSW 0x00000001 /* SW Beacon delay (?) */ -#define AR5K_BSR_BDLYDMA 0x00000002 /* DMA Beacon delay (?) */ -#define AR5K_BSR_TXQ1F 0x00000004 /* Beacon queue (1) finished */ -#define AR5K_BSR_ATIMDLY 0x00000008 /* ATIM delay (?) */ -#define AR5K_BSR_SNPADHOC 0x00000100 /* Ad-hoc mode set (?) */ -#define AR5K_BSR_SNPBDMAE 0x00000200 /* Beacon DMA enabled (?) */ -#define AR5K_BSR_SNPTQ1FV 0x00000400 /* Queue1 is used for CAB traffic (?) */ -#define AR5K_BSR_SNPTQ1V 0x00000800 /* Queue1 is used for Beacon traffic (?) */ -#define AR5K_BSR_SNAPSHOTSVALID 0x00001000 /* BCR snapshots are valid (?) */ -#define AR5K_BSR_SWBA_CNT 0x00ff0000 - -/* - * Second RTS duration register [5211] - */ -#define AR5K_RTSD1 0x002c /* Register Address */ -#define AR5K_RTSD1_24 0x000000ff /* 24Mb */ -#define AR5K_RTSD1_24_S 0 -#define AR5K_RTSD1_36 0x0000ff00 /* 36Mb */ -#define AR5K_RTSD1_36_S 8 -#define AR5K_RTSD1_48 0x00ff0000 /* 48Mb */ -#define AR5K_RTSD1_48_S 16 -#define AR5K_RTSD1_54 0xff000000 /* 54Mb */ -#define AR5K_RTSD1_54_S 24 - - -/* - * Transmit configuration register - */ -#define AR5K_TXCFG 0x0030 /* Register Address */ -#define AR5K_TXCFG_SDMAMR 0x00000007 /* DMA size (read) */ -#define AR5K_TXCFG_SDMAMR_S 0 -#define AR5K_TXCFG_B_MODE 0x00000008 /* Set b mode for 5111 (enable 2111) */ -#define AR5K_TXCFG_TXFSTP 0x00000008 /* TX DMA full Stop [5210] */ -#define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Trigger level mask */ -#define AR5K_TXCFG_TXFULL_S 4 -#define AR5K_TXCFG_TXFULL_0B 0x00000000 -#define AR5K_TXCFG_TXFULL_64B 0x00000010 -#define AR5K_TXCFG_TXFULL_128B 0x00000020 -#define AR5K_TXCFG_TXFULL_192B 0x00000030 -#define AR5K_TXCFG_TXFULL_256B 0x00000040 -#define AR5K_TXCFG_TXCONT_EN 0x00000080 -#define AR5K_TXCFG_DMASIZE 0x00000100 /* Flag for passing DMA size [5210] */ -#define AR5K_TXCFG_JUMBO_DESC_EN 0x00000400 /* Enable jumbo tx descriptors [5211+] */ -#define AR5K_TXCFG_ADHOC_BCN_ATIM 0x00000800 /* Adhoc Beacon ATIM Policy */ -#define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000 /* Disable ATIM window defer [5211+] */ -#define AR5K_TXCFG_RTSRND 0x00001000 /* [5211+] */ -#define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */ -#define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */ -#define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */ -#define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */ -#define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */ - -/* - * Receive configuration register - */ -#define AR5K_RXCFG 0x0034 /* Register Address */ -#define AR5K_RXCFG_SDMAMW 0x00000007 /* DMA size (write) */ -#define AR5K_RXCFG_SDMAMW_S 0 -#define AR5K_RXCFG_ZLFDMA 0x00000008 /* Enable Zero-length frame DMA */ -#define AR5K_RXCFG_DEF_ANTENNA 0x00000010 /* Default antenna (?) */ -#define AR5K_RXCFG_JUMBO_RXE 0x00000020 /* Enable jumbo rx descriptors [5211+] */ -#define AR5K_RXCFG_JUMBO_WRAP 0x00000040 /* Wrap jumbo frames [5211+] */ -#define AR5K_RXCFG_SLE_ENTRY 0x00000080 /* Sleep entry policy */ - -/* - * Receive jumbo descriptor last address register - * Only found in 5211 (?) - */ -#define AR5K_RXJLA 0x0038 - -/* - * MIB control register - */ -#define AR5K_MIBC 0x0040 /* Register Address */ -#define AR5K_MIBC_COW 0x00000001 /* Counter Overflow Warning */ -#define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ -#define AR5K_MIBC_CMC 0x00000004 /* Clear MIB Counters */ -#define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe, increment all */ - -/* - * Timeout prescale register - */ -#define AR5K_TOPS 0x0044 -#define AR5K_TOPS_M 0x0000ffff - -/* - * Receive timeout register (no frame received) - */ -#define AR5K_RXNOFRM 0x0048 -#define AR5K_RXNOFRM_M 0x000003ff - -/* - * Transmit timeout register (no frame sent) - */ -#define AR5K_TXNOFRM 0x004c -#define AR5K_TXNOFRM_M 0x000003ff -#define AR5K_TXNOFRM_QCU 0x000ffc00 -#define AR5K_TXNOFRM_QCU_S 10 - -/* - * Receive frame gap timeout register - */ -#define AR5K_RPGTO 0x0050 -#define AR5K_RPGTO_M 0x000003ff - -/* - * Receive frame count limit register - */ -#define AR5K_RFCNT 0x0054 -#define AR5K_RFCNT_M 0x0000001f /* [5211+] (?) */ -#define AR5K_RFCNT_RFCL 0x0000000f /* [5210] */ - -/* - * Misc settings register - * (reserved0-3) - */ -#define AR5K_MISC 0x0058 /* Register Address */ -#define AR5K_MISC_DMA_OBS_M 0x000001e0 -#define AR5K_MISC_DMA_OBS_S 5 -#define AR5K_MISC_MISC_OBS_M 0x00000e00 -#define AR5K_MISC_MISC_OBS_S 9 -#define AR5K_MISC_MAC_OBS_LSB_M 0x00007000 -#define AR5K_MISC_MAC_OBS_LSB_S 12 -#define AR5K_MISC_MAC_OBS_MSB_M 0x00038000 -#define AR5K_MISC_MAC_OBS_MSB_S 15 -#define AR5K_MISC_LED_DECAY 0x001c0000 /* [5210] */ -#define AR5K_MISC_LED_BLINK 0x00e00000 /* [5210] */ - -/* - * QCU/DCU clock gating register (5311) - * (reserved4-5) - */ -#define AR5K_QCUDCU_CLKGT 0x005c /* Register Address (?) */ -#define AR5K_QCUDCU_CLKGT_QCU 0x0000ffff /* Mask for QCU clock */ -#define AR5K_QCUDCU_CLKGT_DCU 0x07ff0000 /* Mask for DCU clock */ - -/* - * Interrupt Status Registers - * - * For 5210 there is only one status register but for - * 5211/5212 we have one primary and 4 secondary registers. - * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212. - * Most of these bits are common for all chipsets. - * - * NOTE: On 5211+ TXOK, TXDESC, TXERR, TXEOL and TXURN contain - * the logical OR from per-queue interrupt bits found on SISR registers - * (see below). - */ -#define AR5K_ISR 0x001c /* Register Address [5210] */ -#define AR5K_PISR 0x0080 /* Register Address [5211+] */ -#define AR5K_ISR_RXOK 0x00000001 /* Frame successfully received */ -#define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */ -#define AR5K_ISR_RXERR 0x00000004 /* Receive error */ -#define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */ -#define AR5K_ISR_RXEOL 0x00000010 /* Empty RX descriptor */ -#define AR5K_ISR_RXORN 0x00000020 /* Receive FIFO overrun */ -#define AR5K_ISR_TXOK 0x00000040 /* Frame successfully transmitted */ -#define AR5K_ISR_TXDESC 0x00000080 /* TX descriptor request */ -#define AR5K_ISR_TXERR 0x00000100 /* Transmit error */ -#define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmitted (transmit timeout) - * NOTE: We don't have per-queue info for this - * one, but we can enable it per-queue through - * TXNOFRM_QCU field on TXNOFRM register */ -#define AR5K_ISR_TXEOL 0x00000400 /* Empty TX descriptor */ -#define AR5K_ISR_TXURN 0x00000800 /* Transmit FIFO underrun */ -#define AR5K_ISR_MIB 0x00001000 /* Update MIB counters */ -#define AR5K_ISR_SWI 0x00002000 /* Software interrupt */ -#define AR5K_ISR_RXPHY 0x00004000 /* PHY error */ -#define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */ -#define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */ -#define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ -#define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ -#define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] - * 'or' of MCABT, SSERR, DPERR from SISR2 */ -#define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ -#define AR5K_ISR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ -#define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ -#define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ -#define AR5K_ISR_DPERR 0x00400000 /* Bus parity error [5210] */ -#define AR5K_ISR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ -#define AR5K_ISR_TIM 0x00800000 /* [5211+] */ -#define AR5K_ISR_BCNMISC 0x00800000 /* Misc beacon related interrupt - * 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, - * CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ -#define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill) */ -#define AR5K_ISR_QCBRORN 0x02000000 /* QCU CBR overrun [5211+] */ -#define AR5K_ISR_QCBRURN 0x04000000 /* QCU CBR underrun [5211+] */ -#define AR5K_ISR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ - -#define AR5K_ISR_BITS_FROM_SISRS (AR5K_ISR_TXOK | AR5K_ISR_TXDESC |\ - AR5K_ISR_TXERR | AR5K_ISR_TXEOL |\ - AR5K_ISR_TXURN | AR5K_ISR_HIUERR |\ - AR5K_ISR_BCNMISC | AR5K_ISR_QCBRORN |\ - AR5K_ISR_QCBRURN | AR5K_ISR_QTRIG) - -/* - * Secondary status registers [5211+] (0 - 4) - * - * These give the status for each QCU, only QCUs 0-9 are - * represented. - */ -#define AR5K_SISR0 0x0084 /* Register Address [5211+] */ -#define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ -#define AR5K_SISR0_QCU_TXOK_S 0 -#define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ -#define AR5K_SISR0_QCU_TXDESC_S 16 - -#define AR5K_SISR1 0x0088 /* Register Address [5211+] */ -#define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ -#define AR5K_SISR1_QCU_TXERR_S 0 -#define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ -#define AR5K_SISR1_QCU_TXEOL_S 16 - -#define AR5K_SISR2 0x008c /* Register Address [5211+] */ -#define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ -#define AR5K_SISR2_QCU_TXURN_S 0 -#define AR5K_SISR2_MCABT 0x00010000 /* Master Cycle Abort */ -#define AR5K_SISR2_SSERR 0x00020000 /* Signaled System Error */ -#define AR5K_SISR2_DPERR 0x00040000 /* Bus parity error */ -#define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ -#define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ -#define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ -#define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ -#define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ -#define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */ -#define AR5K_SISR2_TSFOOR 0x80000000 /* TSF Out of range */ - -#define AR5K_SISR3 0x0090 /* Register Address [5211+] */ -#define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ -#define AR5K_SISR3_QCBRORN_S 0 -#define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ -#define AR5K_SISR3_QCBRURN_S 16 - -#define AR5K_SISR4 0x0094 /* Register Address [5211+] */ -#define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */ -#define AR5K_SISR4_QTRIG_S 0 - -/* - * Shadow read-and-clear interrupt status registers [5211+] - */ -#define AR5K_RAC_PISR 0x00c0 /* Read and clear PISR */ -#define AR5K_RAC_SISR0 0x00c4 /* Read and clear SISR0 */ -#define AR5K_RAC_SISR1 0x00c8 /* Read and clear SISR1 */ -#define AR5K_RAC_SISR2 0x00cc /* Read and clear SISR2 */ -#define AR5K_RAC_SISR3 0x00d0 /* Read and clear SISR3 */ -#define AR5K_RAC_SISR4 0x00d4 /* Read and clear SISR4 */ - -/* - * Interrupt Mask Registers - * - * As with ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary - * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match. - */ -#define AR5K_IMR 0x0020 /* Register Address [5210] */ -#define AR5K_PIMR 0x00a0 /* Register Address [5211+] */ -#define AR5K_IMR_RXOK 0x00000001 /* Frame successfully received*/ -#define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/ -#define AR5K_IMR_RXERR 0x00000004 /* Receive error*/ -#define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/ -#define AR5K_IMR_RXEOL 0x00000010 /* Empty RX descriptor*/ -#define AR5K_IMR_RXORN 0x00000020 /* Receive FIFO overrun*/ -#define AR5K_IMR_TXOK 0x00000040 /* Frame successfully transmitted*/ -#define AR5K_IMR_TXDESC 0x00000080 /* TX descriptor request*/ -#define AR5K_IMR_TXERR 0x00000100 /* Transmit error*/ -#define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmitted (transmit timeout)*/ -#define AR5K_IMR_TXEOL 0x00000400 /* Empty TX descriptor*/ -#define AR5K_IMR_TXURN 0x00000800 /* Transmit FIFO underrun*/ -#define AR5K_IMR_MIB 0x00001000 /* Update MIB counters*/ -#define AR5K_IMR_SWI 0x00002000 /* Software interrupt */ -#define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/ -#define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */ -#define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/ -#define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ -#define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ -#define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ -#define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ -#define AR5K_IMR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ -#define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ -#define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ -#define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */ -#define AR5K_IMR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ -#define AR5K_IMR_TIM 0x00800000 /* [5211+] */ -#define AR5K_IMR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, - CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ -#define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/ -#define AR5K_IMR_QCBRORN 0x02000000 /* QCU CBR overrun (?) [5211+] */ -#define AR5K_IMR_QCBRURN 0x04000000 /* QCU CBR underrun (?) [5211+] */ -#define AR5K_IMR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ - -/* - * Secondary interrupt mask registers [5211+] (0 - 4) - */ -#define AR5K_SIMR0 0x00a4 /* Register Address [5211+] */ -#define AR5K_SIMR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ -#define AR5K_SIMR0_QCU_TXOK_S 0 -#define AR5K_SIMR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ -#define AR5K_SIMR0_QCU_TXDESC_S 16 - -#define AR5K_SIMR1 0x00a8 /* Register Address [5211+] */ -#define AR5K_SIMR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ -#define AR5K_SIMR1_QCU_TXERR_S 0 -#define AR5K_SIMR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ -#define AR5K_SIMR1_QCU_TXEOL_S 16 - -#define AR5K_SIMR2 0x00ac /* Register Address [5211+] */ -#define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ -#define AR5K_SIMR2_QCU_TXURN_S 0 -#define AR5K_SIMR2_MCABT 0x00010000 /* Master Cycle Abort */ -#define AR5K_SIMR2_SSERR 0x00020000 /* Signaled System Error */ -#define AR5K_SIMR2_DPERR 0x00040000 /* Bus parity error */ -#define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ -#define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ -#define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ -#define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ -#define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ -#define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */ -#define AR5K_SIMR2_TSFOOR 0x80000000 /* TSF OOR (?) */ - -#define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */ -#define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ -#define AR5K_SIMR3_QCBRORN_S 0 -#define AR5K_SIMR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ -#define AR5K_SIMR3_QCBRURN_S 16 - -#define AR5K_SIMR4 0x00b4 /* Register Address [5211+] */ -#define AR5K_SIMR4_QTRIG 0x000003ff /* Mask for QTRIG */ -#define AR5K_SIMR4_QTRIG_S 0 - -/* - * DMA Debug registers 0-7 - * 0xe0 - 0xfc - */ - -/* - * Decompression mask registers [5212+] - */ -#define AR5K_DCM_ADDR 0x0400 /*Decompression mask address (index) */ -#define AR5K_DCM_DATA 0x0404 /*Decompression mask data */ - -/* - * Wake On Wireless pattern control register [5212+] - */ -#define AR5K_WOW_PCFG 0x0410 /* Register Address */ -#define AR5K_WOW_PCFG_PAT_MATCH_EN 0x00000001 /* Pattern match enable */ -#define AR5K_WOW_PCFG_LONG_FRAME_POL 0x00000002 /* Long frame policy */ -#define AR5K_WOW_PCFG_WOBMISS 0x00000004 /* Wake on bea(con) miss (?) */ -#define AR5K_WOW_PCFG_PAT_0_EN 0x00000100 /* Enable pattern 0 */ -#define AR5K_WOW_PCFG_PAT_1_EN 0x00000200 /* Enable pattern 1 */ -#define AR5K_WOW_PCFG_PAT_2_EN 0x00000400 /* Enable pattern 2 */ -#define AR5K_WOW_PCFG_PAT_3_EN 0x00000800 /* Enable pattern 3 */ -#define AR5K_WOW_PCFG_PAT_4_EN 0x00001000 /* Enable pattern 4 */ -#define AR5K_WOW_PCFG_PAT_5_EN 0x00002000 /* Enable pattern 5 */ - -/* - * Wake On Wireless pattern index register (?) [5212+] - */ -#define AR5K_WOW_PAT_IDX 0x0414 - -/* - * Wake On Wireless pattern data register [5212+] - */ -#define AR5K_WOW_PAT_DATA 0x0418 /* Register Address */ -#define AR5K_WOW_PAT_DATA_0_3_V 0x00000001 /* Pattern 0, 3 value */ -#define AR5K_WOW_PAT_DATA_1_4_V 0x00000100 /* Pattern 1, 4 value */ -#define AR5K_WOW_PAT_DATA_2_5_V 0x00010000 /* Pattern 2, 5 value */ -#define AR5K_WOW_PAT_DATA_0_3_M 0x01000000 /* Pattern 0, 3 mask */ -#define AR5K_WOW_PAT_DATA_1_4_M 0x04000000 /* Pattern 1, 4 mask */ -#define AR5K_WOW_PAT_DATA_2_5_M 0x10000000 /* Pattern 2, 5 mask */ - -/* - * Decompression configuration registers [5212+] - */ -#define AR5K_DCCFG 0x0420 /* Register Address */ -#define AR5K_DCCFG_GLOBAL_EN 0x00000001 /* Enable decompression on all queues */ -#define AR5K_DCCFG_BYPASS_EN 0x00000002 /* Bypass decompression */ -#define AR5K_DCCFG_BCAST_EN 0x00000004 /* Enable decompression for bcast frames */ -#define AR5K_DCCFG_MCAST_EN 0x00000008 /* Enable decompression for mcast frames */ - -/* - * Compression configuration registers [5212+] - */ -#define AR5K_CCFG 0x0600 /* Register Address */ -#define AR5K_CCFG_WINDOW_SIZE 0x00000007 /* Compression window size */ -#define AR5K_CCFG_CPC_EN 0x00000008 /* Enable performance counters */ - -#define AR5K_CCFG_CCU 0x0604 /* Register Address */ -#define AR5K_CCFG_CCU_CUP_EN 0x00000001 /* CCU Catchup enable */ -#define AR5K_CCFG_CCU_CREDIT 0x00000002 /* CCU Credit (field) */ -#define AR5K_CCFG_CCU_CD_THRES 0x00000080 /* CCU Cyc(lic?) debt threshold (field) */ -#define AR5K_CCFG_CCU_CUP_LCNT 0x00010000 /* CCU Catchup lit(?) count */ -#define AR5K_CCFG_CCU_INIT 0x00100200 /* Initial value during reset */ - -/* - * Compression performance counter registers [5212+] - */ -#define AR5K_CPC0 0x0610 /* Compression performance counter 0 */ -#define AR5K_CPC1 0x0614 /* Compression performance counter 1*/ -#define AR5K_CPC2 0x0618 /* Compression performance counter 2 */ -#define AR5K_CPC3 0x061c /* Compression performance counter 3 */ -#define AR5K_CPCOVF 0x0620 /* Compression performance overflow */ - - -/* - * Queue control unit (QCU) registers [5211+] - * - * Card has 12 TX Queues but i see that only 0-9 are used (?) - * both in binary HAL (see ah.h) and ar5k. Each queue has it's own - * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate) - * configuration register (0x08c0 - 0x08ec), a ready time configuration - * register (0x0900 - 0x092c), a misc configuration register (0x09c0 - - * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some - * global registers, QCU transmit enable/disable and "one shot arm (?)" - * set/clear, which contain status for all queues (we shift by 1 for each - * queue). To access these registers easily we define some macros here - * that are used inside HAL. For more infos check out *_tx_queue functs. - */ - -/* - * Generic QCU Register access macros - */ -#define AR5K_QUEUE_REG(_r, _q) (((_q) << 2) + _r) -#define AR5K_QCU_GLOBAL_READ(_r, _q) (AR5K_REG_READ(_r) & (1 << _q)) -#define AR5K_QCU_GLOBAL_WRITE(_r, _q) AR5K_REG_WRITE(_r, (1 << _q)) - -/* - * QCU Transmit descriptor pointer registers - */ -#define AR5K_QCU_TXDP_BASE 0x0800 /* Register Address - Queue0 TXDP */ -#define AR5K_QUEUE_TXDP(_q) AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q) - -/* - * QCU Transmit enable register - */ -#define AR5K_QCU_TXE 0x0840 -#define AR5K_ENABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q) -#define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q) - -/* - * QCU Transmit disable register - */ -#define AR5K_QCU_TXD 0x0880 -#define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q) -#define AR5K_QUEUE_DISABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q) - -/* - * QCU Constant Bit Rate configuration registers - */ -#define AR5K_QCU_CBRCFG_BASE 0x08c0 /* Register Address - Queue0 CBRCFG */ -#define AR5K_QCU_CBRCFG_INTVAL 0x00ffffff /* CBR Interval mask */ -#define AR5K_QCU_CBRCFG_INTVAL_S 0 -#define AR5K_QCU_CBRCFG_ORN_THRES 0xff000000 /* CBR overrun threshold mask */ -#define AR5K_QCU_CBRCFG_ORN_THRES_S 24 -#define AR5K_QUEUE_CBRCFG(_q) AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q) - -/* - * QCU Ready time configuration registers - */ -#define AR5K_QCU_RDYTIMECFG_BASE 0x0900 /* Register Address - Queue0 RDYTIMECFG */ -#define AR5K_QCU_RDYTIMECFG_INTVAL 0x00ffffff /* Ready time interval mask */ -#define AR5K_QCU_RDYTIMECFG_INTVAL_S 0 -#define AR5K_QCU_RDYTIMECFG_ENABLE 0x01000000 /* Ready time enable mask */ -#define AR5K_QUEUE_RDYTIMECFG(_q) AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q) - -/* - * QCU one shot arm set registers - */ -#define AR5K_QCU_ONESHOTARM_SET 0x0940 /* Register Address -QCU "one shot arm set (?)" */ -#define AR5K_QCU_ONESHOTARM_SET_M 0x0000ffff - -/* - * QCU one shot arm clear registers - */ -#define AR5K_QCU_ONESHOTARM_CLEAR 0x0980 /* Register Address -QCU "one shot arm clear (?)" */ -#define AR5K_QCU_ONESHOTARM_CLEAR_M 0x0000ffff - -/* - * QCU misc registers - */ -#define AR5K_QCU_MISC_BASE 0x09c0 /* Register Address -Queue0 MISC */ -#define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame scheduling mask */ -#define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ -#define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ -#define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */ -#define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* TIMT gated */ -#define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated */ -#define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */ -#define AR5K_QCU_MISC_CBREXP_DIS 0x00000020 /* Disable CBR expired counter (normal queue) */ -#define AR5K_QCU_MISC_CBREXP_BCN_DIS 0x00000040 /* Disable CBR expired counter (beacon queue) */ -#define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */ -#define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR expired threshold enabled */ -#define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME expired or VEOL */ -#define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */ -#define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */ -#define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */ -#define AR5K_QUEUE_MISC(_q) AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q) - - -/* - * QCU status registers - */ -#define AR5K_QCU_STS_BASE 0x0a00 /* Register Address - Queue0 STS */ -#define AR5K_QCU_STS_FRMPENDCNT 0x00000003 /* Frames pending counter */ -#define AR5K_QCU_STS_CBREXPCNT 0x0000ff00 /* CBR expired counter */ -#define AR5K_QUEUE_STATUS(_q) AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q) - -/* - * QCU ready time shutdown register - */ -#define AR5K_QCU_RDYTIMESHDN 0x0a40 -#define AR5K_QCU_RDYTIMESHDN_M 0x000003ff - -/* - * QCU compression buffer base registers [5212+] - */ -#define AR5K_QCU_CBB_SELECT 0x0b00 -#define AR5K_QCU_CBB_ADDR 0x0b04 -#define AR5K_QCU_CBB_ADDR_S 9 - -/* - * QCU compression buffer configuration register [5212+] - * (buffer size) - */ -#define AR5K_QCU_CBCFG 0x0b08 - - - -/* - * Distributed Coordination Function (DCF) control unit (DCU) - * registers [5211+] - * - * These registers control the various characteristics of each queue - * for 802.11e (WME) compatibility so they go together with - * QCU registers in pairs. For each queue we have a QCU mask register, - * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c), - * a retry limit register (0x1080 - 0x10ac), a channel time register - * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and - * a sequence number register (0x1140 - 0x116c). It seems that "global" - * registers here affect all queues (see use of DCU_GBL_IFS_SLOT in ar5k). - * We use the same macros here for easier register access. - * - */ - -/* - * DCU QCU mask registers - */ -#define AR5K_DCU_QCUMASK_BASE 0x1000 /* Register Address -Queue0 DCU_QCUMASK */ -#define AR5K_DCU_QCUMASK_M 0x000003ff -#define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q) - -/* - * DCU local Inter Frame Space settings register - */ -#define AR5K_DCU_LCL_IFS_BASE 0x1040 /* Register Address -Queue0 DCU_LCL_IFS */ -#define AR5K_DCU_LCL_IFS_CW_MIN 0x000003ff /* Minimum Contention Window */ -#define AR5K_DCU_LCL_IFS_CW_MIN_S 0 -#define AR5K_DCU_LCL_IFS_CW_MAX 0x000ffc00 /* Maximum Contention Window */ -#define AR5K_DCU_LCL_IFS_CW_MAX_S 10 -#define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */ -#define AR5K_DCU_LCL_IFS_AIFS_S 20 -#define AR5K_DCU_LCL_IFS_AIFS_MAX 0xfc /* Anything above that can cause DCU to hang */ -#define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q) - -/* - * DCU retry limit registers - * all these fields don't allow zero values - */ -#define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ -#define AR5K_DCU_RETRY_LMT_RTS 0x0000000f /* RTS failure limit. Transmission fails if no CTS is received for this number of times */ -#define AR5K_DCU_RETRY_LMT_RTS_S 0 -#define AR5K_DCU_RETRY_LMT_STA_RTS 0x00003f00 /* STA RTS failure limit. If exceeded CW reset */ -#define AR5K_DCU_RETRY_LMT_STA_RTS_S 8 -#define AR5K_DCU_RETRY_LMT_STA_DATA 0x000fc000 /* STA data failure limit. If exceeded CW reset. */ -#define AR5K_DCU_RETRY_LMT_STA_DATA_S 14 -#define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) - -/* - * DCU channel time registers - */ -#define AR5K_DCU_CHAN_TIME_BASE 0x10c0 /* Register Address -Queue0 DCU_CHAN_TIME */ -#define AR5K_DCU_CHAN_TIME_DUR 0x000fffff /* Channel time duration */ -#define AR5K_DCU_CHAN_TIME_DUR_S 0 -#define AR5K_DCU_CHAN_TIME_ENABLE 0x00100000 /* Enable channel time */ -#define AR5K_QUEUE_DFS_CHANNEL_TIME(_q) AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q) - -/* - * DCU misc registers [5211+] - * - * Note: Arbiter lockout control controls the - * behaviour on low priority queues when we have multiple queues - * with pending frames. Intra-frame lockout means we wait until - * the queue's current frame transmits (with post frame backoff and bursting) - * before we transmit anything else and global lockout means we - * wait for the whole queue to finish before higher priority queues - * can transmit (this is used on beacon and CAB queues). - * No lockout means there is no special handling. - */ -#define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */ -#define AR5K_DCU_MISC_BACKOFF 0x0000003f /* Mask for backoff threshold */ -#define AR5K_DCU_MISC_ETS_RTS_POL 0x00000040 /* End of transmission series - station RTS/data failure count - reset policy (?) */ -#define AR5K_DCU_MISC_ETS_CW_POL 0x00000080 /* End of transmission series - CW reset policy */ -#define AR5K_DCU_MISC_FRAG_WAIT 0x00000100 /* Wait for next fragment */ -#define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */ -#define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */ -#define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */ -#define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */ -#define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */ -#define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 -#define AR5K_DCU_MISC_VIRTCOL_IGNORE 1 -#define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */ -#define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */ -#define AR5K_DCU_MISC_ARBLOCK_CTL_S 17 -#define AR5K_DCU_MISC_ARBLOCK_CTL_NONE 0 /* No arbiter lockout */ -#define AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM 1 /* Intra-frame lockout */ -#define AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL 2 /* Global lockout */ -#define AR5K_DCU_MISC_ARBLOCK_IGNORE 0x00080000 /* Ignore Arbiter lockout */ -#define AR5K_DCU_MISC_SEQ_NUM_INCR_DIS 0x00100000 /* Disable sequence number increment */ -#define AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000 /* Disable post-frame backoff */ -#define AR5K_DCU_MISC_VIRT_COLL_POLICY 0x00400000 /* Virtual Collision cw policy */ -#define AR5K_DCU_MISC_BLOWN_IFS_POLICY 0x00800000 /* Blown IFS policy (?) */ -#define AR5K_DCU_MISC_SEQNUM_CTL 0x01000000 /* Sequence number control (?) */ -#define AR5K_QUEUE_DFS_MISC(_q) AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q) - -/* - * DCU frame sequence number registers - */ -#define AR5K_DCU_SEQNUM_BASE 0x1140 -#define AR5K_DCU_SEQNUM_M 0x00000fff -#define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q) - -/* - * DCU global IFS SIFS register - */ -#define AR5K_DCU_GBL_IFS_SIFS 0x1030 -#define AR5K_DCU_GBL_IFS_SIFS_M 0x0000ffff - -/* - * DCU global IFS slot interval register - */ -#define AR5K_DCU_GBL_IFS_SLOT 0x1070 -#define AR5K_DCU_GBL_IFS_SLOT_M 0x0000ffff - -/* - * DCU global IFS EIFS register - */ -#define AR5K_DCU_GBL_IFS_EIFS 0x10b0 -#define AR5K_DCU_GBL_IFS_EIFS_M 0x0000ffff - -/* - * DCU global IFS misc register - * - * LFSR stands for Linear Feedback Shift Register - * and it's used for generating pseudo-random - * number sequences. - * - * (If i understand correctly, random numbers are - * used for idle sensing -multiplied with cwmin/max etc-) - */ -#define AR5K_DCU_GBL_IFS_MISC 0x10f0 /* Register Address */ -#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */ -#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ -#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ -#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC_S 4 -#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ -#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 -#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ -#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFS cnt reset policy (?) */ -#define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */ -#define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */ - -/* - * DCU frame prefetch control register - */ -#define AR5K_DCU_FP 0x1230 /* Register Address */ -#define AR5K_DCU_FP_NOBURST_DCU_EN 0x00000001 /* Enable non-burst prefetch on DCU (?) */ -#define AR5K_DCU_FP_NOBURST_EN 0x00000010 /* Enable non-burst prefetch (?) */ -#define AR5K_DCU_FP_BURST_DCU_EN 0x00000020 /* Enable burst prefetch on DCU (?) */ - -/* - * DCU transmit pause control/status register - */ -#define AR5K_DCU_TXP 0x1270 /* Register Address */ -#define AR5K_DCU_TXP_M 0x000003ff /* Tx pause mask */ -#define AR5K_DCU_TXP_STATUS 0x00010000 /* Tx pause status */ - -/* - * DCU transmit filter table 0 (32 entries) - * each entry contains a 32bit slice of the - * 128bit tx filter for each DCU (4 slices per DCU) - */ -#define AR5K_DCU_TX_FILTER_0_BASE 0x1038 -#define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64)) - -/* - * DCU transmit filter table 1 (16 entries) - */ -#define AR5K_DCU_TX_FILTER_1_BASE 0x103c -#define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64)) - -/* - * DCU clear transmit filter register - */ -#define AR5K_DCU_TX_FILTER_CLR 0x143c - -/* - * DCU set transmit filter register - */ -#define AR5K_DCU_TX_FILTER_SET 0x147c - -/* - * Reset control register - */ -#define AR5K_RESET_CTL 0x4000 /* Register Address */ -#define AR5K_RESET_CTL_PCU 0x00000001 /* Protocol Control Unit reset */ -#define AR5K_RESET_CTL_DMA 0x00000002 /* DMA (Rx/Tx) reset [5210] */ -#define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset [5211+] */ -#define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */ -#define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */ -#define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */ - -/* - * Sleep control register - */ -#define AR5K_SLEEP_CTL 0x4004 /* Register Address */ -#define AR5K_SLEEP_CTL_SLDUR 0x0000ffff /* Sleep duration mask */ -#define AR5K_SLEEP_CTL_SLDUR_S 0 -#define AR5K_SLEEP_CTL_SLE 0x00030000 /* Sleep enable mask */ -#define AR5K_SLEEP_CTL_SLE_S 16 -#define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */ -#define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */ -#define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 /* Normal sleep policy */ -#define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */ -#define AR5K_SLEEP_CTL_DUR_TIM_POL 0x00040000 /* Sleep duration timing policy */ -#define AR5K_SLEEP_CTL_DUR_WRITE_POL 0x00080000 /* Sleep duration write policy */ -#define AR5K_SLEEP_CTL_SLE_POL 0x00100000 /* Sleep policy mode */ - -/* - * Interrupt pending register - */ -#define AR5K_INTPEND 0x4008 -#define AR5K_INTPEND_M 0x00000001 - -/* - * Sleep force register - */ -#define AR5K_SFR 0x400c -#define AR5K_SFR_EN 0x00000001 - -/* - * PCI configuration register - * TODO: Fix LED stuff - */ -#define AR5K_PCICFG 0x4010 /* Register Address */ -#define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */ -#define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock */ -#define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */ -#define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */ -#define AR5K_PCICFG_EESIZE_S 3 -#define AR5K_PCICFG_EESIZE_4K 0 /* 4K */ -#define AR5K_PCICFG_EESIZE_8K 1 /* 8K */ -#define AR5K_PCICFG_EESIZE_16K 2 /* 16K */ -#define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size [5211+] */ -#define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */ -#define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */ -#define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */ -#define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */ -#define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */ -#define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix */ -#define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ -#define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ -#define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ -#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even with pending interrupts*/ -#define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ -#define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ -#define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ -#define AR5K_PCICFG_LEDMODE_PROM 0x00020000 /* Default mode (blink on any traffic) [5211+] */ -#define AR5K_PCICFG_LEDMODE_PWR 0x00040000 /* Some other blinking mode (?) [5211+] */ -#define AR5K_PCICFG_LEDMODE_RAND 0x00060000 /* Random blinking (?) [5211+] */ -#define AR5K_PCICFG_LEDBLINK 0x00700000 /* Led blink rate */ -#define AR5K_PCICFG_LEDBLINK_S 20 -#define AR5K_PCICFG_LEDSLOW 0x00800000 /* Slowest led blink rate [5211+] */ -#define AR5K_PCICFG_LEDSTATE \ - (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \ - AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW) -#define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate */ -#define AR5K_PCICFG_SLEEP_CLOCK_RATE_S 24 - -/* - * "General Purpose Input/Output" (GPIO) control register - * - * I'm not sure about this but after looking at the code - * for all chipsets here is what i got. - * - * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits) - * Mode 0 -> always input - * Mode 1 -> output when GPIODO for this GPIO is set to 0 - * Mode 2 -> output when GPIODO for this GPIO is set to 1 - * Mode 3 -> always output - * - * For more infos check out get_gpio/set_gpio and - * set_gpio_input/set_gpio_output functs. - * For more infos on gpio interrupt check out set_gpio_intr. - */ -#define AR5K_NUM_GPIO 6 - -#define AR5K_GPIOCR 0x4014 /* Register Address */ -#define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */ -#define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is low */ -#define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is high */ -#define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */ -#define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */ -#define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */ -#define AR5K_GPIOCR_OUT(n) (3 << ((n) * 2)) /* Mode 3 for pin n */ -#define AR5K_GPIOCR_INT_SEL(n) ((n) << 12) /* Interrupt for GPIO pin n */ - -/* - * "General Purpose Input/Output" (GPIO) data output register - */ -#define AR5K_GPIODO 0x4018 - -/* - * "General Purpose Input/Output" (GPIO) data input register - */ -#define AR5K_GPIODI 0x401c -#define AR5K_GPIODI_M 0x0000002f - -/* - * Silicon revision register - */ -#define AR5K_SREV 0x4020 /* Register Address */ -#define AR5K_SREV_REV 0x0000000f /* Mask for revision */ -#define AR5K_SREV_REV_S 0 -#define AR5K_SREV_VER 0x000000ff /* Mask for version */ -#define AR5K_SREV_VER_S 4 - -/* - * TXE write posting register - */ -#define AR5K_TXEPOST 0x4028 - -/* - * QCU sleep mask - */ -#define AR5K_QCU_SLEEP_MASK 0x402c - -/* 0x4068 is compression buffer configuration - * register on 5414 and pm configuration register - * on 5424 and newer pci-e chips. */ - -/* - * Compression buffer configuration - * register (enable/disable) [5414] - */ -#define AR5K_5414_CBCFG 0x4068 -#define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */ - -/* - * PCI-E Power management configuration - * and status register [5424+] - */ -#define AR5K_PCIE_PM_CTL 0x4068 /* Register address */ -/* Only 5424 */ -#define AR5K_PCIE_PM_CTL_L1_WHEN_D2 0x00000001 /* enable PCIe core enter L1 - when d2_sleep_en is asserted */ -#define AR5K_PCIE_PM_CTL_L0_L0S_CLEAR 0x00000002 /* Clear L0 and L0S counters */ -#define AR5K_PCIE_PM_CTL_L0_L0S_EN 0x00000004 /* Start L0 nd L0S counters */ -#define AR5K_PCIE_PM_CTL_LDRESET_EN 0x00000008 /* Enable reset when link goes - down */ -/* Wake On Wireless */ -#define AR5K_PCIE_PM_CTL_PME_EN 0x00000010 /* PME Enable */ -#define AR5K_PCIE_PM_CTL_AUX_PWR_DET 0x00000020 /* Aux power detect */ -#define AR5K_PCIE_PM_CTL_PME_CLEAR 0x00000040 /* Clear PME */ -#define AR5K_PCIE_PM_CTL_PSM_D0 0x00000080 -#define AR5K_PCIE_PM_CTL_PSM_D1 0x00000100 -#define AR5K_PCIE_PM_CTL_PSM_D2 0x00000200 -#define AR5K_PCIE_PM_CTL_PSM_D3 0x00000400 - -/* - * PCI-E Workaround enable register - */ -#define AR5K_PCIE_WAEN 0x407c - -/* - * PCI-E Serializer/Deserializer - * registers - */ -#define AR5K_PCIE_SERDES 0x4080 -#define AR5K_PCIE_SERDES_RESET 0x4084 - -/*====EEPROM REGISTERS====*/ - -/* - * EEPROM access registers - * - * Here we got a difference between 5210/5211-12 - * read data register for 5210 is at 0x6800 and - * status register is at 0x6c00. There is also - * no eeprom command register on 5210 and the - * offsets are different. - * - * To read eeprom data for a specific offset: - * 5210 - enable eeprom access (AR5K_PCICFG_EEAE) - * read AR5K_EEPROM_BASE +(4 * offset) - * check the eeprom status register - * and read eeprom data register. - * - * 5211 - write offset to AR5K_EEPROM_BASE - * 5212 write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD - * check the eeprom status register - * and read eeprom data register. - * - * To write eeprom data for a specific offset: - * 5210 - enable eeprom access (AR5K_PCICFG_EEAE) - * write data to AR5K_EEPROM_BASE +(4 * offset) - * check the eeprom status register - * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD - * 5212 write offset to AR5K_EEPROM_BASE - * write data to data register - * write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD - * check the eeprom status register - * - * For more infos check eeprom_* functs and the ar5k.c - * file posted in madwifi-devel mailing list. - * http://sourceforge.net/mailarchive/message.php?msg_id=8966525 - * - */ -#define AR5K_EEPROM_BASE 0x6000 - -/* - * EEPROM data register - */ -#define AR5K_EEPROM_DATA_5211 0x6004 -#define AR5K_EEPROM_DATA_5210 0x6800 -#define AR5K_EEPROM_DATA (ah->ah_version == AR5K_AR5210 ? \ - AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211) - -/* - * EEPROM command register - */ -#define AR5K_EEPROM_CMD 0x6008 /* Register Address */ -#define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ -#define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ -#define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ - -/* - * EEPROM status register - */ -#define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */ -#define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */ -#define AR5K_EEPROM_STATUS (ah->ah_version == AR5K_AR5210 ? \ - AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211) -#define AR5K_EEPROM_STAT_RDERR 0x00000001 /* EEPROM read failed */ -#define AR5K_EEPROM_STAT_RDDONE 0x00000002 /* EEPROM read successful */ -#define AR5K_EEPROM_STAT_WRERR 0x00000004 /* EEPROM write failed */ -#define AR5K_EEPROM_STAT_WRDONE 0x00000008 /* EEPROM write successful */ - -/* - * EEPROM config register - */ -#define AR5K_EEPROM_CFG 0x6010 /* Register Address */ -#define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ -#define AR5K_EEPROM_CFG_SIZE_AUTO 0 -#define AR5K_EEPROM_CFG_SIZE_4KBIT 1 -#define AR5K_EEPROM_CFG_SIZE_8KBIT 2 -#define AR5K_EEPROM_CFG_SIZE_16KBIT 3 -#define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */ -#define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */ -#define AR5K_EEPROM_CFG_CLK_RATE_S 3 -#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ 0 -#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ 1 -#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ 2 -#define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protection key */ -#define AR5K_EEPROM_CFG_PROT_KEY_S 8 -#define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */ - - -/* - * TODO: Wake On Wireless registers - * Range 0x7000 - 0x7ce0 - */ - -/* - * Protocol Control Unit (PCU) registers - */ -/* - * Used for checking initial register writes - * during channel reset (see reset func) - */ -#define AR5K_PCU_MIN 0x8000 -#define AR5K_PCU_MAX 0x8fff - -/* - * First station id register (Lower 32 bits of MAC address) - */ -#define AR5K_STA_ID0 0x8000 -#define AR5K_STA_ID0_ARRD_L32 0xffffffff - -/* - * Second station id register (Upper 16 bits of MAC address + PCU settings) - */ -#define AR5K_STA_ID1 0x8004 /* Register Address */ -#define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC address */ -#define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ -#define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ -#define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ -#define AR5K_STA_ID1_NO_KEYSRCH 0x00080000 /* No key search */ -#define AR5K_STA_ID1_NO_PSPOLL 0x00100000 /* No power save polling [5210] */ -#define AR5K_STA_ID1_PCF_5211 0x00100000 /* Enable PCF on [5211+] */ -#define AR5K_STA_ID1_PCF_5210 0x00200000 /* Enable PCF on [5210]*/ -#define AR5K_STA_ID1_PCF (ah->ah_version == AR5K_AR5210 ? \ - AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211) -#define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */ -#define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ -#define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ -#define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Rate to use for ACK/CTS. 0: highest mandatory rate <= RX rate; 1: 1Mbps in B mode */ -#define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* 802.11b base rate. 0: 1, 2, 5.5 and 11Mbps; 1: 1 and 2Mbps. [5211+] */ -#define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ -#define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ -#define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ -#define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */ -#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ -#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ - -#define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \ - AR5K_STA_ID1_DESC_ANTENNA | \ - AR5K_STA_ID1_RTS_DEF_ANTENNA | \ - AR5K_STA_ID1_SELFGEN_DEF_ANT) - -/* - * First BSSID register (MAC address, lower 32bits) - */ -#define AR5K_BSS_ID0 0x8008 - -/* - * Second BSSID register (MAC address in upper 16 bits) - * - * AID: Association ID - */ -#define AR5K_BSS_ID1 0x800c -#define AR5K_BSS_ID1_AID 0xffff0000 -#define AR5K_BSS_ID1_AID_S 16 - -/* - * Backoff slot time register - */ -#define AR5K_SLOT_TIME 0x8010 - -/* - * ACK/CTS timeout register - */ -#define AR5K_TIME_OUT 0x8014 /* Register Address */ -#define AR5K_TIME_OUT_ACK 0x00001fff /* ACK timeout mask */ -#define AR5K_TIME_OUT_ACK_S 0 -#define AR5K_TIME_OUT_CTS 0x1fff0000 /* CTS timeout mask */ -#define AR5K_TIME_OUT_CTS_S 16 - -/* - * RSSI threshold register - */ -#define AR5K_RSSI_THR 0x8018 /* Register Address */ -#define AR5K_RSSI_THR_M 0x000000ff /* Mask for RSSI threshold [5211+] */ -#define AR5K_RSSI_THR_BMISS_5210 0x00000700 /* Mask for Beacon Missed threshold [5210] */ -#define AR5K_RSSI_THR_BMISS_5210_S 8 -#define AR5K_RSSI_THR_BMISS_5211 0x0000ff00 /* Mask for Beacon Missed threshold [5211+] */ -#define AR5K_RSSI_THR_BMISS_5211_S 8 -#define AR5K_RSSI_THR_BMISS (ah->ah_version == AR5K_AR5210 ? \ - AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211) -#define AR5K_RSSI_THR_BMISS_S 8 - -/* - * 5210 has more PCU registers because there is no QCU/DCU - * so queue parameters are set here, this way a lot common - * registers have different address for 5210. To make things - * easier we define a macro based on ah->ah_version for common - * registers with different addresses and common flags. - */ - -/* - * Retry limit register - * - * Retry limit register for 5210 (no QCU/DCU so it's done in PCU) - */ -#define AR5K_NODCU_RETRY_LMT 0x801c /* Register Address */ -#define AR5K_NODCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ -#define AR5K_NODCU_RETRY_LMT_SH_RETRY_S 0 -#define AR5K_NODCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry mask */ -#define AR5K_NODCU_RETRY_LMT_LG_RETRY_S 4 -#define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask */ -#define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S 8 -#define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask */ -#define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S 14 -#define AR5K_NODCU_RETRY_LMT_CW_MIN 0x3ff00000 /* Minimum contention window mask */ -#define AR5K_NODCU_RETRY_LMT_CW_MIN_S 20 - -/* - * Transmit latency register - */ -#define AR5K_USEC_5210 0x8020 /* Register Address [5210] */ -#define AR5K_USEC_5211 0x801c /* Register Address [5211+] */ -#define AR5K_USEC (ah->ah_version == AR5K_AR5210 ? \ - AR5K_USEC_5210 : AR5K_USEC_5211) -#define AR5K_USEC_1 0x0000007f /* clock cycles for 1us */ -#define AR5K_USEC_1_S 0 -#define AR5K_USEC_32 0x00003f80 /* clock cycles for 1us while on 32MHz clock */ -#define AR5K_USEC_32_S 7 -#define AR5K_USEC_TX_LATENCY_5211 0x007fc000 -#define AR5K_USEC_TX_LATENCY_5211_S 14 -#define AR5K_USEC_RX_LATENCY_5211 0x1f800000 -#define AR5K_USEC_RX_LATENCY_5211_S 23 -#define AR5K_USEC_TX_LATENCY_5210 0x000fc000 /* also for 5311 */ -#define AR5K_USEC_TX_LATENCY_5210_S 14 -#define AR5K_USEC_RX_LATENCY_5210 0x03f00000 /* also for 5311 */ -#define AR5K_USEC_RX_LATENCY_5210_S 20 - -/* - * PCU beacon control register - */ -#define AR5K_BEACON_5210 0x8024 /*Register Address [5210] */ -#define AR5K_BEACON_5211 0x8020 /*Register Address [5211+] */ -#define AR5K_BEACON (ah->ah_version == AR5K_AR5210 ? \ - AR5K_BEACON_5210 : AR5K_BEACON_5211) -#define AR5K_BEACON_PERIOD 0x0000ffff /* Mask for beacon period */ -#define AR5K_BEACON_PERIOD_S 0 -#define AR5K_BEACON_TIM 0x007f0000 /* Mask for TIM offset */ -#define AR5K_BEACON_TIM_S 16 -#define AR5K_BEACON_ENABLE 0x00800000 /* Enable beacons */ -#define AR5K_BEACON_RESET_TSF 0x01000000 /* Force TSF reset */ - -/* - * CFP period register - */ -#define AR5K_CFP_PERIOD_5210 0x8028 -#define AR5K_CFP_PERIOD_5211 0x8024 -#define AR5K_CFP_PERIOD (ah->ah_version == AR5K_AR5210 ? \ - AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211) - -/* - * Next beacon time register - */ -#define AR5K_TIMER0_5210 0x802c -#define AR5K_TIMER0_5211 0x8028 -#define AR5K_TIMER0 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_TIMER0_5210 : AR5K_TIMER0_5211) - -/* - * Next DMA beacon alert register - */ -#define AR5K_TIMER1_5210 0x8030 -#define AR5K_TIMER1_5211 0x802c -#define AR5K_TIMER1 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_TIMER1_5210 : AR5K_TIMER1_5211) - -/* - * Next software beacon alert register - */ -#define AR5K_TIMER2_5210 0x8034 -#define AR5K_TIMER2_5211 0x8030 -#define AR5K_TIMER2 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_TIMER2_5210 : AR5K_TIMER2_5211) - -/* - * Next ATIM window time register - */ -#define AR5K_TIMER3_5210 0x8038 -#define AR5K_TIMER3_5211 0x8034 -#define AR5K_TIMER3 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_TIMER3_5210 : AR5K_TIMER3_5211) - - -/* - * 5210 First inter frame spacing register (IFS) - */ -#define AR5K_IFS0 0x8040 -#define AR5K_IFS0_SIFS 0x000007ff -#define AR5K_IFS0_SIFS_S 0 -#define AR5K_IFS0_DIFS 0x007ff800 -#define AR5K_IFS0_DIFS_S 11 - -/* - * 5210 Second inter frame spacing register (IFS) - */ -#define AR5K_IFS1 0x8044 -#define AR5K_IFS1_PIFS 0x00000fff -#define AR5K_IFS1_PIFS_S 0 -#define AR5K_IFS1_EIFS 0x03fff000 -#define AR5K_IFS1_EIFS_S 12 -#define AR5K_IFS1_CS_EN 0x04000000 -#define AR5K_IFS1_CS_EN_S 26 - -/* - * CFP duration register - */ -#define AR5K_CFP_DUR_5210 0x8048 -#define AR5K_CFP_DUR_5211 0x8038 -#define AR5K_CFP_DUR (ah->ah_version == AR5K_AR5210 ? \ - AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211) - -/* - * Receive filter register - */ -#define AR5K_RX_FILTER_5210 0x804c /* Register Address [5210] */ -#define AR5K_RX_FILTER_5211 0x803c /* Register Address [5211+] */ -#define AR5K_RX_FILTER (ah->ah_version == AR5K_AR5210 ? \ - AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211) -#define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */ -#define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */ -#define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */ -#define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */ -#define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */ -#define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */ -#define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */ -#define AR5K_RX_FILTER_PROBEREQ 0x00000080 /* Don't filter probe requests [5212+] */ -#define AR5K_RX_FILTER_PHYERR_5212 0x00000100 /* Don't filter phy errors [5212+] */ -#define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */ -#define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */ -#define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */ -#define AR5K_RX_FILTER_PHYERR \ - ((ah->ah_version == AR5K_AR5211 ? \ - AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212)) -#define AR5K_RX_FILTER_RADARERR \ - ((ah->ah_version == AR5K_AR5211 ? \ - AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212)) - -/* - * Multicast filter register (lower 32 bits) - */ -#define AR5K_MCAST_FILTER0_5210 0x8050 -#define AR5K_MCAST_FILTER0_5211 0x8040 -#define AR5K_MCAST_FILTER0 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211) - -/* - * Multicast filter register (higher 16 bits) - */ -#define AR5K_MCAST_FILTER1_5210 0x8054 -#define AR5K_MCAST_FILTER1_5211 0x8044 -#define AR5K_MCAST_FILTER1 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211) - - -/* - * Transmit mask register (lower 32 bits) [5210] - */ -#define AR5K_TX_MASK0 0x8058 - -/* - * Transmit mask register (higher 16 bits) [5210] - */ -#define AR5K_TX_MASK1 0x805c - -/* - * Clear transmit mask [5210] - */ -#define AR5K_CLR_TMASK 0x8060 - -/* - * Trigger level register (before transmission) [5210] - */ -#define AR5K_TRIG_LVL 0x8064 - - -/* - * PCU Diagnostic register - * - * Used for tweaking/diagnostics. - */ -#define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ -#define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ -#define AR5K_DIAG_SW (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211) -#define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ -#define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ -#define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ -#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable HW encryption */ -#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable HW decryption */ -#define AR5K_DIAG_SW_DIS_TX_5210 0x00000020 /* Disable transmit [5210] */ -#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable receive */ -#define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 -#define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) -#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* TX Data Loopback (i guess it goes with DIS_TX) [5210] */ -#define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 -#define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) -#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Generate invalid TX FCS */ -#define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 -#define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) -#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Add 56 bytes of channel info before the frame data in the RX buffer */ -#define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 -#define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) -#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 /* Enable fixed scrambler seed */ -#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 -#define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211) -#define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */ -#define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ -#define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ -#define AR5K_DIAG_SW_SCRAM_SEED_S 10 -#define AR5K_DIAG_SW_DIS_SEQ_INC_5210 0x00040000 /* Disable seqnum increment (?)[5210] */ -#define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 -#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ -#define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) -#define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ -#define AR5K_DIAG_SW_OBSPT_S 18 -#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x00100000 /* Ignore carrier sense */ -#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x00200000 /* Ignore virtual carrier sense */ -#define AR5K_DIAG_SW_CHANNEL_IDLE_HIGH 0x00400000 /* Force channel idle high */ -#define AR5K_DIAG_SW_PHEAR_ME 0x00800000 /* ??? */ - -/* - * TSF (clock) register (lower 32 bits) - */ -#define AR5K_TSF_L32_5210 0x806c -#define AR5K_TSF_L32_5211 0x804c -#define AR5K_TSF_L32 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211) - -/* - * TSF (clock) register (higher 32 bits) - */ -#define AR5K_TSF_U32_5210 0x8070 -#define AR5K_TSF_U32_5211 0x8050 -#define AR5K_TSF_U32 (ah->ah_version == AR5K_AR5210 ? \ - AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211) - -/* - * Last beacon timestamp register (Read Only) - */ -#define AR5K_LAST_TSTP 0x8080 - -/* - * ADDAC test register [5211+] - */ -#define AR5K_ADDAC_TEST 0x8054 /* Register Address */ -#define AR5K_ADDAC_TEST_TXCONT 0x00000001 /* Test continuous tx */ -#define AR5K_ADDAC_TEST_TST_MODE 0x00000002 /* Test mode */ -#define AR5K_ADDAC_TEST_LOOP_EN 0x00000004 /* Enable loop */ -#define AR5K_ADDAC_TEST_LOOP_LEN 0x00000008 /* Loop length (field) */ -#define AR5K_ADDAC_TEST_USE_U8 0x00004000 /* Use upper 8 bits */ -#define AR5K_ADDAC_TEST_MSB 0x00008000 /* State of MSB */ -#define AR5K_ADDAC_TEST_TRIG_SEL 0x00010000 /* Trigger select */ -#define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */ -#define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */ -#define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */ -#define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */ - -/* - * Default antenna register [5211+] - */ -#define AR5K_DEFAULT_ANTENNA 0x8058 - -/* - * Frame control QoS mask register (?) [5211+] - * (FC_QOS_MASK) - */ -#define AR5K_FRAME_CTL_QOSM 0x805c - -/* - * Seq mask register (?) [5211+] - */ -#define AR5K_SEQ_MASK 0x8060 - -/* - * Retry count register [5210] - */ -#define AR5K_RETRY_CNT 0x8084 /* Register Address [5210] */ -#define AR5K_RETRY_CNT_SSH 0x0000003f /* Station short retry count (?) */ -#define AR5K_RETRY_CNT_SLG 0x00000fc0 /* Station long retry count (?) */ - -/* - * Back-off status register [5210] - */ -#define AR5K_BACKOFF 0x8088 /* Register Address [5210] */ -#define AR5K_BACKOFF_CW 0x000003ff /* Backoff Contention Window (?) */ -#define AR5K_BACKOFF_CNT 0x03ff0000 /* Backoff count (?) */ - - - -/* - * NAV register (current) - */ -#define AR5K_NAV_5210 0x808c -#define AR5K_NAV_5211 0x8084 -#define AR5K_NAV (ah->ah_version == AR5K_AR5210 ? \ - AR5K_NAV_5210 : AR5K_NAV_5211) - -/* - * MIB counters: - * - * max value is 0xc000, if this is reached we get a MIB interrupt. - * they can be controlled via AR5K_MIBC and are cleared on read. - */ - -/* - * RTS success (MIB counter) - */ -#define AR5K_RTS_OK_5210 0x8090 -#define AR5K_RTS_OK_5211 0x8088 -#define AR5K_RTS_OK (ah->ah_version == AR5K_AR5210 ? \ - AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) - -/* - * RTS failure (MIB counter) - */ -#define AR5K_RTS_FAIL_5210 0x8094 -#define AR5K_RTS_FAIL_5211 0x808c -#define AR5K_RTS_FAIL (ah->ah_version == AR5K_AR5210 ? \ - AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) - -/* - * ACK failure (MIB counter) - */ -#define AR5K_ACK_FAIL_5210 0x8098 -#define AR5K_ACK_FAIL_5211 0x8090 -#define AR5K_ACK_FAIL (ah->ah_version == AR5K_AR5210 ? \ - AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) - -/* - * FCS failure (MIB counter) - */ -#define AR5K_FCS_FAIL_5210 0x809c -#define AR5K_FCS_FAIL_5211 0x8094 -#define AR5K_FCS_FAIL (ah->ah_version == AR5K_AR5210 ? \ - AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211) - -/* - * Beacon count register - */ -#define AR5K_BEACON_CNT_5210 0x80a0 -#define AR5K_BEACON_CNT_5211 0x8098 -#define AR5K_BEACON_CNT (ah->ah_version == AR5K_AR5210 ? \ - AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211) - - -/*===5212 Specific PCU registers===*/ - -/* - * Transmit power control register - */ -#define AR5K_TPC 0x80e8 -#define AR5K_TPC_ACK 0x0000003f /* ack frames */ -#define AR5K_TPC_ACK_S 0 -#define AR5K_TPC_CTS 0x00003f00 /* cts frames */ -#define AR5K_TPC_CTS_S 8 -#define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */ -#define AR5K_TPC_CHIRP_S 16 -#define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */ -#define AR5K_TPC_DOPPLER_S 24 - -/* - * XR (eXtended Range) mode register - */ -#define AR5K_XRMODE 0x80c0 /* Register Address */ -#define AR5K_XRMODE_POLL_TYPE_M 0x0000003f /* Mask for Poll type (?) */ -#define AR5K_XRMODE_POLL_TYPE_S 0 -#define AR5K_XRMODE_POLL_SUBTYPE_M 0x0000003c /* Mask for Poll subtype (?) */ -#define AR5K_XRMODE_POLL_SUBTYPE_S 2 -#define AR5K_XRMODE_POLL_WAIT_ALL 0x00000080 /* Wait for poll */ -#define AR5K_XRMODE_SIFS_DELAY 0x000fff00 /* Mask for SIFS delay */ -#define AR5K_XRMODE_FRAME_HOLD_M 0xfff00000 /* Mask for frame hold (?) */ -#define AR5K_XRMODE_FRAME_HOLD_S 20 - -/* - * XR delay register - */ -#define AR5K_XRDELAY 0x80c4 /* Register Address */ -#define AR5K_XRDELAY_SLOT_DELAY_M 0x0000ffff /* Mask for slot delay */ -#define AR5K_XRDELAY_SLOT_DELAY_S 0 -#define AR5K_XRDELAY_CHIRP_DELAY_M 0xffff0000 /* Mask for CHIRP data delay */ -#define AR5K_XRDELAY_CHIRP_DELAY_S 16 - -/* - * XR timeout register - */ -#define AR5K_XRTIMEOUT 0x80c8 /* Register Address */ -#define AR5K_XRTIMEOUT_CHIRP_M 0x0000ffff /* Mask for CHIRP timeout */ -#define AR5K_XRTIMEOUT_CHIRP_S 0 -#define AR5K_XRTIMEOUT_POLL_M 0xffff0000 /* Mask for Poll timeout */ -#define AR5K_XRTIMEOUT_POLL_S 16 - -/* - * XR chirp register - */ -#define AR5K_XRCHIRP 0x80cc /* Register Address */ -#define AR5K_XRCHIRP_SEND 0x00000001 /* Send CHIRP */ -#define AR5K_XRCHIRP_GAP 0xffff0000 /* Mask for CHIRP gap (?) */ - -/* - * XR stomp register - */ -#define AR5K_XRSTOMP 0x80d0 /* Register Address */ -#define AR5K_XRSTOMP_TX 0x00000001 /* Stomp Tx (?) */ -#define AR5K_XRSTOMP_RX 0x00000002 /* Stomp Rx (?) */ -#define AR5K_XRSTOMP_TX_RSSI 0x00000004 /* Stomp Tx RSSI (?) */ -#define AR5K_XRSTOMP_TX_BSSID 0x00000008 /* Stomp Tx BSSID (?) */ -#define AR5K_XRSTOMP_DATA 0x00000010 /* Stomp data (?)*/ -#define AR5K_XRSTOMP_RSSI_THRES 0x0000ff00 /* Mask for XR RSSI threshold */ - -/* - * First enhanced sleep register - */ -#define AR5K_SLEEP0 0x80d4 /* Register Address */ -#define AR5K_SLEEP0_NEXT_DTIM 0x0007ffff /* Mask for next DTIM (?) */ -#define AR5K_SLEEP0_NEXT_DTIM_S 0 -#define AR5K_SLEEP0_ASSUME_DTIM 0x00080000 /* Assume DTIM */ -#define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000 /* Enable enhanced sleep control */ -#define AR5K_SLEEP0_CABTO 0xff000000 /* Mask for CAB Time Out */ -#define AR5K_SLEEP0_CABTO_S 24 - -/* - * Second enhanced sleep register - */ -#define AR5K_SLEEP1 0x80d8 /* Register Address */ -#define AR5K_SLEEP1_NEXT_TIM 0x0007ffff /* Mask for next TIM (?) */ -#define AR5K_SLEEP1_NEXT_TIM_S 0 -#define AR5K_SLEEP1_BEACON_TO 0xff000000 /* Mask for Beacon Time Out */ -#define AR5K_SLEEP1_BEACON_TO_S 24 - -/* - * Third enhanced sleep register - */ -#define AR5K_SLEEP2 0x80dc /* Register Address */ -#define AR5K_SLEEP2_TIM_PER 0x0000ffff /* Mask for TIM period (?) */ -#define AR5K_SLEEP2_TIM_PER_S 0 -#define AR5K_SLEEP2_DTIM_PER 0xffff0000 /* Mask for DTIM period (?) */ -#define AR5K_SLEEP2_DTIM_PER_S 16 - -/* - * TX power control (TPC) register - * - * XXX: PCDAC steps (0.5dBm) or dBm ? - * - */ -#define AR5K_TXPC 0x80e8 /* Register Address */ -#define AR5K_TXPC_ACK_M 0x0000003f /* ACK tx power */ -#define AR5K_TXPC_ACK_S 0 -#define AR5K_TXPC_CTS_M 0x00003f00 /* CTS tx power */ -#define AR5K_TXPC_CTS_S 8 -#define AR5K_TXPC_CHIRP_M 0x003f0000 /* CHIRP tx power */ -#define AR5K_TXPC_CHIRP_S 16 -#define AR5K_TXPC_DOPPLER 0x0f000000 /* Doppler chirp span (?) */ -#define AR5K_TXPC_DOPPLER_S 24 - -/* - * Profile count registers - * - * These registers can be cleared and frozen with ATH5K_MIBC, but they do not - * generate a MIB interrupt. - * Instead of overflowing, they shift by one bit to the right. All registers - * shift together, i.e. when one reaches the max, all shift at the same time by - * one bit to the right. This way we should always get consistent values. - */ -#define AR5K_PROFCNT_TX 0x80ec /* Tx count */ -#define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ -#define AR5K_PROFCNT_RXCLR 0x80f4 /* Busy count */ -#define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle counter */ - -/* - * Quiet period control registers - */ -#define AR5K_QUIET_CTL1 0x80fc /* Register Address */ -#define AR5K_QUIET_CTL1_NEXT_QT_TSF 0x0000ffff /* Next quiet period TSF (TU) */ -#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S 0 -#define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet period */ -#define AR5K_QUIET_CTL1_ACK_CTS_EN 0x00020000 /* Send ACK/CTS during quiet period */ - -#define AR5K_QUIET_CTL2 0x8100 /* Register Address */ -#define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period periodicity */ -#define AR5K_QUIET_CTL2_QT_PER_S 0 -#define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet period duration */ -#define AR5K_QUIET_CTL2_QT_DUR_S 16 - -/* - * TSF parameter register - */ -#define AR5K_TSF_PARM 0x8104 /* Register Address */ -#define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */ -#define AR5K_TSF_PARM_INC_S 0 - -/* - * QoS NOACK policy - */ -#define AR5K_QOS_NOACK 0x8108 /* Register Address */ -#define AR5K_QOS_NOACK_2BIT_VALUES 0x0000000f /* ??? */ -#define AR5K_QOS_NOACK_2BIT_VALUES_S 0 -#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ -#define AR5K_QOS_NOACK_BIT_OFFSET_S 4 -#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ -#define AR5K_QOS_NOACK_BYTE_OFFSET_S 7 - -/* - * PHY error filter register - */ -#define AR5K_PHY_ERR_FIL 0x810c -#define AR5K_PHY_ERR_FIL_RADAR 0x00000020 /* Radar signal */ -#define AR5K_PHY_ERR_FIL_OFDM 0x00020000 /* OFDM false detect (ANI) */ -#define AR5K_PHY_ERR_FIL_CCK 0x02000000 /* CCK false detect (ANI) */ - -/* - * XR latency register - */ -#define AR5K_XRLAT_TX 0x8110 - -/* - * ACK SIFS register - */ -#define AR5K_ACKSIFS 0x8114 /* Register Address */ -#define AR5K_ACKSIFS_INC 0x00000000 /* ACK SIFS Increment (field) */ - -/* - * MIC QoS control register (?) - */ -#define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ -#define AR5K_MIC_QOS_CTL_OFF(_n) (1 << (_n * 2)) -#define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ - -/* - * MIC QoS select register (?) - */ -#define AR5K_MIC_QOS_SEL 0x811c -#define AR5K_MIC_QOS_SEL_OFF(_n) (1 << (_n * 4)) - -/* - * Misc mode control register (?) - */ -#define AR5K_MISC_MODE 0x8120 /* Register Address */ -#define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */ -#define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */ -#define AR5K_MISC_MODE_COMBINED_MIC 0x00000004 /* use rx/tx MIC key */ -/* more bits */ - -/* - * OFDM Filter counter - */ -#define AR5K_OFDM_FIL_CNT 0x8124 - -/* - * CCK Filter counter - */ -#define AR5K_CCK_FIL_CNT 0x8128 - -/* - * PHY Error Counters (same masks as AR5K_PHY_ERR_FIL) - */ -#define AR5K_PHYERR_CNT1 0x812c -#define AR5K_PHYERR_CNT1_MASK 0x8130 - -#define AR5K_PHYERR_CNT2 0x8134 -#define AR5K_PHYERR_CNT2_MASK 0x8138 - -/* if the PHY Error Counters reach this maximum, we get MIB interrupts */ -#define ATH5K_PHYERR_CNT_MAX 0x00c00000 - -/* - * TSF Threshold register (?) - */ -#define AR5K_TSF_THRES 0x813c - -/* - * TODO: Wake On Wireless registers - * Range: 0x8147 - 0x818c - */ - -/* - * Rate -> ACK SIFS mapping table (32 entries) - */ -#define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */ -#define AR5K_RATE_ACKSIFS(_n) (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2)) -#define AR5K_RATE_ACKSIFS_NORMAL 0x00000001 /* Normal SIFS (field) */ -#define AR5K_RATE_ACKSIFS_TURBO 0x00000400 /* Turbo SIFS (field) */ - -/* - * Rate -> duration mapping table (32 entries) - */ -#define AR5K_RATE_DUR_BASE 0x8700 -#define AR5K_RATE_DUR(_n) (AR5K_RATE_DUR_BASE + ((_n) << 2)) - -/* - * Rate -> db mapping table - * (8 entries, each one has 4 8bit fields) - */ -#define AR5K_RATE2DB_BASE 0x87c0 -#define AR5K_RATE2DB(_n) (AR5K_RATE2DB_BASE + ((_n) << 2)) - -/* - * db -> Rate mapping table - * (8 entries, each one has 4 8bit fields) - */ -#define AR5K_DB2RATE_BASE 0x87e0 -#define AR5K_DB2RATE(_n) (AR5K_DB2RATE_BASE + ((_n) << 2)) - -/*===5212 end===*/ - -#define AR5K_KEYTABLE_SIZE_5210 64 -#define AR5K_KEYTABLE_SIZE_5211 128 - -/*===PHY REGISTERS===*/ - -/* - * PHY registers start - */ -#define AR5K_PHY_BASE 0x9800 -#define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2)) - -/* - * TST_2 (Misc config parameters) - */ -#define AR5K_PHY_TST2 0x9800 /* Register Address */ -#define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/ -#define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */ -#define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */ -#define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32kHz external) */ -#define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ -#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ -#define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ -#define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */ -#define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */ -#define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */ -#define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */ -#define AR5K_PHY_TST2_AGC_OBS_SEL_3 0x00040000 /* AGC OBS Select 3 (?) */ -#define AR5K_PHY_TST2_BBB_OBS_SEL 0x00080000 /* BB OBS Select (field ?) */ -#define AR5K_PHY_TST2_ADC_OBS_SEL 0x00800000 /* ADC OBS Select (field ?) */ -#define AR5K_PHY_TST2_RX_CLR_SEL 0x08000000 /* RX Clear Select (?) */ -#define AR5K_PHY_TST2_FORCE_AGC_CLR 0x10000000 /* Force AGC clear (?) */ -#define AR5K_PHY_SHIFT_2GHZ 0x00004007 /* Used to access 2GHz radios */ -#define AR5K_PHY_SHIFT_5GHZ 0x00000007 /* Used to access 5GHz radios (default) */ - -/* - * PHY frame control register [5110] /turbo mode register [5111+] - * - * There is another frame control register for [5111+] - * at address 0x9944 (see below) but the 2 first flags - * are common here between 5110 frame control register - * and [5111+] turbo mode register, so this also works as - * a "turbo mode register" for 5110. We treat this one as - * a frame control register for 5110 below. - */ -#define AR5K_PHY_TURBO 0x9804 /* Register Address */ -#define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ -#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ -#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */ - -/* - * PHY agility command register - * (aka TST_1) - */ -#define AR5K_PHY_AGC 0x9808 /* Register Address */ -#define AR5K_PHY_TST1 0x9808 -#define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/ -#define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */ -#define AR5K_PHY_TST1_TXSRC_SRC 0x00000002 /* Used with bit 7 (?) */ -#define AR5K_PHY_TST1_TXSRC_SRC_S 1 -#define AR5K_PHY_TST1_TXSRC_ALT 0x00000080 /* Set input to tsdac (?) */ -#define AR5K_PHY_TST1_TXSRC_ALT_S 7 - - -/* - * PHY timing register 3 [5112+] - */ -#define AR5K_PHY_TIMING_3 0x9814 -#define AR5K_PHY_TIMING_3_DSC_MAN 0xfffe0000 -#define AR5K_PHY_TIMING_3_DSC_MAN_S 17 -#define AR5K_PHY_TIMING_3_DSC_EXP 0x0001e000 -#define AR5K_PHY_TIMING_3_DSC_EXP_S 13 - -/* - * PHY chip revision register - */ -#define AR5K_PHY_CHIP_ID 0x9818 - -/* - * PHY activation register - */ -#define AR5K_PHY_ACT 0x981c /* Register Address */ -#define AR5K_PHY_ACT_ENABLE 0x00000001 /* Activate PHY */ -#define AR5K_PHY_ACT_DISABLE 0x00000002 /* Deactivate PHY */ - -/* - * PHY RF control registers - */ -#define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */ -#define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* TX frame to TX data start */ -#define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 - -#define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ -#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */ -#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8 - -#define AR5K_PHY_ADC_CTL 0x982c -#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 -#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S 0 -#define AR5K_PHY_ADC_CTL_PWD_DAC_OFF 0x00002000 -#define AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF 0x00004000 -#define AR5K_PHY_ADC_CTL_PWD_ADC_OFF 0x00008000 -#define AR5K_PHY_ADC_CTL_INBUFGAIN_ON 0x00030000 -#define AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S 16 - -#define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */ -#define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */ -#define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON 0x00000100 /* TX frame to XPA B on (field) */ -#define AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF 0x00010000 /* TX end to XPA A off (field) */ -#define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000 /* TX end to XPA B off (field) */ - -/* - * Pre-Amplifier control register - * (XPA -> external pre-amplifier) - */ -#define AR5K_PHY_PA_CTL 0x9838 /* Register Address */ -#define AR5K_PHY_PA_CTL_XPA_A_HI 0x00000001 /* XPA A high (?) */ -#define AR5K_PHY_PA_CTL_XPA_B_HI 0x00000002 /* XPA B high (?) */ -#define AR5K_PHY_PA_CTL_XPA_A_EN 0x00000004 /* Enable XPA A */ -#define AR5K_PHY_PA_CTL_XPA_B_EN 0x00000008 /* Enable XPA B */ - -/* - * PHY settling register - */ -#define AR5K_PHY_SETTLING 0x9844 /* Register Address */ -#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ -#define AR5K_PHY_SETTLING_AGC_S 0 -#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settling time */ -#define AR5K_PHY_SETTLING_SWITCH_S 7 - -/* - * PHY Gain registers - */ -#define AR5K_PHY_GAIN 0x9848 /* Register Address */ -#define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* TX-RX Attenuation */ -#define AR5K_PHY_GAIN_TXRX_ATTEN_S 12 -#define AR5K_PHY_GAIN_TXRX_RF_MAX 0x007c0000 -#define AR5K_PHY_GAIN_TXRX_RF_MAX_S 18 - -#define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */ -#define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ - -/* - * Desired ADC/PGA size register - * (for more infos read ANI patent) - */ -#define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ -#define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* ADC desired size */ -#define AR5K_PHY_DESIRED_SIZE_ADC_S 0 -#define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* PGA desired size */ -#define AR5K_PHY_DESIRED_SIZE_PGA_S 8 -#define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Total desired size */ -#define AR5K_PHY_DESIRED_SIZE_TOT_S 20 - -/* - * PHY signal register - * (for more infos read ANI patent) - */ -#define AR5K_PHY_SIG 0x9858 /* Register Address */ -#define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* FIRSTEP */ -#define AR5K_PHY_SIG_FIRSTEP_S 12 -#define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* FIPWR */ -#define AR5K_PHY_SIG_FIRPWR_S 18 - -/* - * PHY coarse agility control register - * (for more infos read ANI patent) - */ -#define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */ -#define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* AGC Coarse low */ -#define AR5K_PHY_AGCCOARSE_LO_S 7 -#define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* AGC Coarse high */ -#define AR5K_PHY_AGCCOARSE_HI_S 15 - -/* - * PHY agility control register - */ -#define AR5K_PHY_AGCCTL 0x9860 /* Register address */ -#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ -#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ -#define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */ -#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ -#define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */ -#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automatically */ - -/* - * PHY noise floor status register (CCA = Clear Channel Assessment) - */ -#define AR5K_PHY_NF 0x9864 /* Register address */ -#define AR5K_PHY_NF_M 0x000001ff /* Noise floor, written to hardware in 1/2 dBm units */ -#define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9)) -#define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */ -#define AR5K_PHY_NF_THRESH62_S 12 -#define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* Minimum measured noise level, read from hardware in 1 dBm units */ -#define AR5K_PHY_NF_MINCCA_PWR_S 19 - -/* - * PHY ADC saturation register [5110] - */ -#define AR5K_PHY_ADCSAT 0x9868 -#define AR5K_PHY_ADCSAT_ICNT 0x0001f800 -#define AR5K_PHY_ADCSAT_ICNT_S 11 -#define AR5K_PHY_ADCSAT_THR 0x000007e0 -#define AR5K_PHY_ADCSAT_THR_S 5 - -/* - * PHY Weak ofdm signal detection threshold registers (ANI) [5212+] - */ - -/* High thresholds */ -#define AR5K_PHY_WEAK_OFDM_HIGH_THR 0x9868 -#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT 0x0000001f -#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0 -#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1 0x00fe0000 -#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S 17 -#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2 0x7f000000 -#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S 24 - -/* Low thresholds */ -#define AR5K_PHY_WEAK_OFDM_LOW_THR 0x986c -#define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN 0x00000001 -#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT 0x00003f00 -#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S 8 -#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1 0x001fc000 -#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S 14 -#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2 0x0fe00000 -#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S 21 - - -/* - * PHY sleep registers [5112+] - */ -#define AR5K_PHY_SCR 0x9870 - -#define AR5K_PHY_SLMT 0x9874 -#define AR5K_PHY_SLMT_32MHZ 0x0000007f - -#define AR5K_PHY_SCAL 0x9878 -#define AR5K_PHY_SCAL_32MHZ 0x0000000e -#define AR5K_PHY_SCAL_32MHZ_5311 0x00000008 -#define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a -#define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032 - -/* - * PHY PLL (Phase Locked Loop) control register - */ -#define AR5K_PHY_PLL 0x987c -#define AR5K_PHY_PLL_20MHZ 0x00000013 /* For half rate (?) */ -/* 40MHz -> 5GHz band */ -#define AR5K_PHY_PLL_40MHZ_5211 0x00000018 -#define AR5K_PHY_PLL_40MHZ_5212 0x000000aa -#define AR5K_PHY_PLL_40MHZ_5413 0x00000004 -#define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \ - AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212) -/* 44MHz -> 2.4GHz band */ -#define AR5K_PHY_PLL_44MHZ_5211 0x00000019 -#define AR5K_PHY_PLL_44MHZ_5212 0x000000ab -#define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \ - AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212) - -#define AR5K_PHY_PLL_RF5111 0x00000000 -#define AR5K_PHY_PLL_RF5112 0x00000040 -#define AR5K_PHY_PLL_HALF_RATE 0x00000100 -#define AR5K_PHY_PLL_QUARTER_RATE 0x00000200 - -/* - * RF Buffer register - * - * It's obvious from the code that 0x989c is the buffer register but - * for the other special registers that we write to after sending each - * packet, i have no idea. So I'll name them BUFFER_CONTROL_X registers - * for now. It's interesting that they are also used for some other operations. - */ - -#define AR5K_RF_BUFFER 0x989c -#define AR5K_RF_BUFFER_CONTROL_0 0x98c0 /* Channel on 5110 */ -#define AR5K_RF_BUFFER_CONTROL_1 0x98c4 /* Bank 7 on 5112 */ -#define AR5K_RF_BUFFER_CONTROL_2 0x98cc /* Bank 7 on 5111 */ - -#define AR5K_RF_BUFFER_CONTROL_3 0x98d0 /* Bank 2 on 5112 */ - /* Channel set on 5111 */ - /* Used to read radio revision*/ - -#define AR5K_RF_BUFFER_CONTROL_4 0x98d4 /* RF Stage register on 5110 */ - /* Bank 0,1,2,6 on 5111 */ - /* Bank 1 on 5112 */ - /* Used during activation on 5111 */ - -#define AR5K_RF_BUFFER_CONTROL_5 0x98d8 /* Bank 3 on 5111 */ - /* Used during activation on 5111 */ - /* Channel on 5112 */ - /* Bank 6 on 5112 */ - -#define AR5K_RF_BUFFER_CONTROL_6 0x98dc /* Bank 3 on 5112 */ - -/* - * PHY RF stage register [5210] - */ -#define AR5K_PHY_RFSTG 0x98d4 -#define AR5K_PHY_RFSTG_DISABLE 0x00000021 - -/* - * BIN masks (?) - */ -#define AR5K_PHY_BIN_MASK_1 0x9900 -#define AR5K_PHY_BIN_MASK_2 0x9904 -#define AR5K_PHY_BIN_MASK_3 0x9908 - -#define AR5K_PHY_BIN_MASK_CTL 0x990c -#define AR5K_PHY_BIN_MASK_CTL_MASK_4 0x00003fff -#define AR5K_PHY_BIN_MASK_CTL_MASK_4_S 0 -#define AR5K_PHY_BIN_MASK_CTL_RATE 0xff000000 -#define AR5K_PHY_BIN_MASK_CTL_RATE_S 24 - -/* - * PHY Antenna control register - */ -#define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */ -#define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */ -#define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */ -#define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */ -#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */ -#define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4 - -/* - * PHY receiver delay register [5111+] - */ -#define AR5K_PHY_RX_DELAY 0x9914 /* Register Address */ -#define AR5K_PHY_RX_DELAY_M 0x00003fff /* Mask for RX activate to receive delay (/100ns) */ - -/* - * PHY max rx length register (?) [5111] - */ -#define AR5K_PHY_MAX_RX_LEN 0x991c - -/* - * PHY timing register 4 - * I(nphase)/Q(adrature) calibration register [5111+] - */ -#define AR5K_PHY_IQ 0x9920 /* Register Address */ -#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ -#define AR5K_PHY_IQ_CORR_Q_Q_COFF_S 0 -#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ -#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 -#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ -#define AR5K_PHY_IQ_CAL_NUM_LOG_MAX 0x0000f000 /* Mask for max number of samples in log scale */ -#define AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S 12 -#define AR5K_PHY_IQ_RUN 0x00010000 /* Run i/q calibration */ -#define AR5K_PHY_IQ_USE_PT_DF 0x00020000 /* Use pilot track df (?) */ -#define AR5K_PHY_IQ_EARLY_TRIG_THR 0x00200000 /* Early trigger threshold (?) (field) */ -#define AR5K_PHY_IQ_PILOT_MASK_EN 0x10000000 /* Enable pilot mask (?) */ -#define AR5K_PHY_IQ_CHAN_MASK_EN 0x20000000 /* Enable channel mask (?) */ -#define AR5K_PHY_IQ_SPUR_FILT_EN 0x40000000 /* Enable spur filter */ -#define AR5K_PHY_IQ_SPUR_RSSI_EN 0x80000000 /* Enable spur rssi */ - -/* - * PHY timing register 5 - * OFDM Self-correlator Cyclic RSSI threshold params - * (Check out bb_cycpwr_thr1 on ANI patent) - */ -#define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ -#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ -#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ -#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1 -#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ -#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ -#define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ -#define AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI 0x00800000 /* Long sc threshold hi rssi (?) */ - -/* - * PHY-only warm reset register - */ -#define AR5K_PHY_WARM_RESET 0x9928 - -/* - * PHY-only control register - */ -#define AR5K_PHY_CTL 0x992c /* Register Address */ -#define AR5K_PHY_CTL_RX_DRAIN_RATE 0x00000001 /* RX drain rate (?) */ -#define AR5K_PHY_CTL_LATE_TX_SIG_SYM 0x00000002 /* Late tx signal symbol (?) */ -#define AR5K_PHY_CTL_GEN_SCRAMBLER 0x00000004 /* Generate scrambler */ -#define AR5K_PHY_CTL_TX_ANT_SEL 0x00000008 /* TX antenna select */ -#define AR5K_PHY_CTL_TX_ANT_STATIC 0x00000010 /* Static TX antenna */ -#define AR5K_PHY_CTL_RX_ANT_SEL 0x00000020 /* RX antenna select */ -#define AR5K_PHY_CTL_RX_ANT_STATIC 0x00000040 /* Static RX antenna */ -#define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */ - -/* - * PHY PAPD probe register [5111+] - */ -#define AR5K_PHY_PAPD_PROBE 0x9930 -#define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001 -#define AR5K_PHY_PAPD_PROBE_PCDAC_BIAS 0x00000002 -#define AR5K_PHY_PAPD_PROBE_COMP_GAIN 0x00000040 -#define AR5K_PHY_PAPD_PROBE_TXPOWER 0x00007e00 -#define AR5K_PHY_PAPD_PROBE_TXPOWER_S 9 -#define AR5K_PHY_PAPD_PROBE_TX_NEXT 0x00008000 -#define AR5K_PHY_PAPD_PROBE_PREDIST_EN 0x00010000 -#define AR5K_PHY_PAPD_PROBE_TYPE 0x01800000 /* [5112+] */ -#define AR5K_PHY_PAPD_PROBE_TYPE_S 23 -#define AR5K_PHY_PAPD_PROBE_TYPE_OFDM 0 -#define AR5K_PHY_PAPD_PROBE_TYPE_XR 1 -#define AR5K_PHY_PAPD_PROBE_TYPE_CCK 2 -#define AR5K_PHY_PAPD_PROBE_GAINF 0xfe000000 -#define AR5K_PHY_PAPD_PROBE_GAINF_S 25 -#define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */ -#define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */ - -/* - * PHY TX rate power registers [5112+] - */ -#define AR5K_PHY_TXPOWER_RATE1 0x9934 -#define AR5K_PHY_TXPOWER_RATE2 0x9938 -#define AR5K_PHY_TXPOWER_RATE_MAX 0x993c -#define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE 0x00000040 -#define AR5K_PHY_TXPOWER_RATE3 0xa234 -#define AR5K_PHY_TXPOWER_RATE4 0xa238 - -/* - * PHY frame control register [5111+] - */ -#define AR5K_PHY_FRAME_CTL_5210 0x9804 -#define AR5K_PHY_FRAME_CTL_5211 0x9944 -#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \ - AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211) -/*---[5111+]---*/ -#define AR5K_PHY_FRAME_CTL_WIN_LEN 0x00000003 /* Force window length (?) */ -#define AR5K_PHY_FRAME_CTL_WIN_LEN_S 0 -#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ -#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 -#define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ -#define AR5K_PHY_FRAME_CTL_EMU 0x80000000 -#define AR5K_PHY_FRAME_CTL_EMU_S 31 -/*---[5110/5111]---*/ -#define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */ -#define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */ -#define AR5K_PHY_FRAME_CTL_ILLRATE_ERR 0x04000000 /* Illegal rate */ -#define AR5K_PHY_FRAME_CTL_ILLLEN_ERR 0x08000000 /* Illegal length */ -#define AR5K_PHY_FRAME_CTL_SERVICE_ERR 0x20000000 -#define AR5K_PHY_FRAME_CTL_TXURN_ERR 0x40000000 /* TX underrun */ -#define AR5K_PHY_FRAME_CTL_INI \ - (AR5K_PHY_FRAME_CTL_SERVICE_ERR | \ - AR5K_PHY_FRAME_CTL_TXURN_ERR | \ - AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \ - AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \ - AR5K_PHY_FRAME_CTL_PARITY_ERR | \ - AR5K_PHY_FRAME_CTL_TIMING_ERR) - -/* - * PHY Tx Power adjustment register [5212A+] - */ -#define AR5K_PHY_TX_PWR_ADJ 0x994c -#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0 -#define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6 -#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000 -#define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18 - -/* - * PHY radar detection register [5111+] - */ -#define AR5K_PHY_RADAR 0x9954 -#define AR5K_PHY_RADAR_ENABLE 0x00000001 -#define AR5K_PHY_RADAR_DISABLE 0x00000000 -#define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold - 5-bits, units unknown {0..31} - (? MHz ?) */ -#define AR5K_PHY_RADAR_INBANDTHR_S 1 - -#define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold - 6-bits, dBm range {0..63} - in dBm units. */ -#define AR5K_PHY_RADAR_PRSSI_THR_S 6 - -#define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold - 6-bits, dBm range {0..63} - in dBm units. */ -#define AR5K_PHY_RADAR_PHEIGHT_THR_S 12 - -#define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. - 6-bits, dBm range {0..63} - in dBm units. */ -#define AR5K_PHY_RADAR_RSSI_THR_S 18 - -#define AR5K_PHY_RADAR_FIRPWR_THR 0x7f000000 /* Finite Impulse Response - filter power out threshold. - 7-bits, standard power range - {0..127} in 1/2 dBm units. */ -#define AR5K_PHY_RADAR_FIRPWR_THRS 24 - -/* - * PHY antenna switch table registers - */ -#define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960 -#define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964 - -/* - * PHY Noise floor threshold - */ -#define AR5K_PHY_NFTHRES 0x9968 - -/* - * Sigma Delta register (?) [5213] - */ -#define AR5K_PHY_SIGMA_DELTA 0x996C -#define AR5K_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 -#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0 -#define AR5K_PHY_SIGMA_DELTA_FILT2 0x000000f8 -#define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 -#define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 -#define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 -#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 -#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 - -/* - * RF restart register [5112+] (?) - */ -#define AR5K_PHY_RESTART 0x9970 /* restart */ -#define AR5K_PHY_RESTART_DIV_GC 0x001c0000 /* Fast diversity gc_limit (?) */ -#define AR5K_PHY_RESTART_DIV_GC_S 18 - -/* - * RF Bus access request register (for synth-only channel switching) - */ -#define AR5K_PHY_RFBUS_REQ 0x997C -#define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001 - -/* - * Spur mitigation masks (?) - */ -#define AR5K_PHY_TIMING_7 0x9980 -#define AR5K_PHY_TIMING_8 0x9984 -#define AR5K_PHY_TIMING_8_PILOT_MASK_2 0x000fffff -#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S 0 - -#define AR5K_PHY_BIN_MASK2_1 0x9988 -#define AR5K_PHY_BIN_MASK2_2 0x998c -#define AR5K_PHY_BIN_MASK2_3 0x9990 - -#define AR5K_PHY_BIN_MASK2_4 0x9994 -#define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff -#define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0 - -#define AR5K_PHY_TIMING_9 0x9998 -#define AR5K_PHY_TIMING_10 0x999c -#define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff -#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0 - -/* - * Spur mitigation control - */ -#define AR5K_PHY_TIMING_11 0x99a0 /* Register address */ -#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */ -#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0 -#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */ -#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20 -#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */ -#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */ - -/* - * Gain tables - */ -#define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ -#define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) -#define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplifier Gain table base address */ -#define AR5K_RF_GAIN(_n) (AR5K_RF_GAIN_BASE + ((_n) << 2)) - -/* - * PHY timing IQ calibration result register [5111+] - */ -#define AR5K_PHY_IQRES_CAL_PWR_I 0x9c10 /* I (Inphase) power value */ -#define AR5K_PHY_IQRES_CAL_PWR_Q 0x9c14 /* Q (Quadrature) power value */ -#define AR5K_PHY_IQRES_CAL_CORR 0x9c18 /* I/Q Correlation */ - -/* - * PHY current RSSI register [5111+] - */ -#define AR5K_PHY_CURRENT_RSSI 0x9c1c - -/* - * PHY RF Bus grant register - */ -#define AR5K_PHY_RFBUS_GRANT 0x9c20 -#define AR5K_PHY_RFBUS_GRANT_OK 0x00000001 - -/* - * PHY ADC test register - */ -#define AR5K_PHY_ADC_TEST 0x9c24 -#define AR5K_PHY_ADC_TEST_I 0x00000001 -#define AR5K_PHY_ADC_TEST_Q 0x00000200 - -/* - * PHY DAC test register - */ -#define AR5K_PHY_DAC_TEST 0x9c28 -#define AR5K_PHY_DAC_TEST_I 0x00000001 -#define AR5K_PHY_DAC_TEST_Q 0x00000200 - -/* - * PHY PTAT register (?) - */ -#define AR5K_PHY_PTAT 0x9c2c - -/* - * PHY Illegal TX rate register [5112+] - */ -#define AR5K_PHY_BAD_TX_RATE 0x9c30 - -/* - * PHY SPUR Power register [5112+] - */ -#define AR5K_PHY_SPUR_PWR 0x9c34 /* Register Address */ -#define AR5K_PHY_SPUR_PWR_I 0x00000001 /* SPUR Power estimate for I (field) */ -#define AR5K_PHY_SPUR_PWR_Q 0x00000100 /* SPUR Power estimate for Q (field) */ -#define AR5K_PHY_SPUR_PWR_FILT 0x00010000 /* Power with SPUR removed (field) */ - -/* - * PHY Channel status register [5112+] (?) - */ -#define AR5K_PHY_CHAN_STATUS 0x9c38 -#define AR5K_PHY_CHAN_STATUS_BT_ACT 0x00000001 -#define AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002 -#define AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004 -#define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008 - -/* - * Heavy clip enable register - */ -#define AR5K_PHY_HEAVY_CLIP_ENABLE 0x99e0 - -/* - * PHY clock sleep registers [5112+] - */ -#define AR5K_PHY_SCLOCK 0x99f0 -#define AR5K_PHY_SCLOCK_32MHZ 0x0000000c -#define AR5K_PHY_SDELAY 0x99f4 -#define AR5K_PHY_SDELAY_32MHZ 0x000000ff -#define AR5K_PHY_SPENDING 0x99f8 - - -/* - * PHY PAPD I (power?) table (?) - * (92! entries) - */ -#define AR5K_PHY_PAPD_I_BASE 0xa000 -#define AR5K_PHY_PAPD_I(_n) (AR5K_PHY_PAPD_I_BASE + ((_n) << 2)) - -/* - * PHY PCDAC TX power table - */ -#define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180 -#define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2)) - -/* - * PHY mode register [5111+] - */ -#define AR5K_PHY_MODE 0x0a200 /* Register Address */ -#define AR5K_PHY_MODE_MOD 0x00000001 /* PHY Modulation bit */ -#define AR5K_PHY_MODE_MOD_OFDM 0 -#define AR5K_PHY_MODE_MOD_CCK 1 -#define AR5K_PHY_MODE_FREQ 0x00000002 /* Freq mode bit */ -#define AR5K_PHY_MODE_FREQ_5GHZ 0 -#define AR5K_PHY_MODE_FREQ_2GHZ 2 -#define AR5K_PHY_MODE_MOD_DYN 0x00000004 /* Enable Dynamic OFDM/CCK mode [5112+] */ -#define AR5K_PHY_MODE_RAD 0x00000008 /* [5212+] */ -#define AR5K_PHY_MODE_RAD_RF5111 0 -#define AR5K_PHY_MODE_RAD_RF5112 8 -#define AR5K_PHY_MODE_XR 0x00000010 /* Enable XR mode [5112+] */ -#define AR5K_PHY_MODE_HALF_RATE 0x00000020 /* Enable Half rate (test) */ -#define AR5K_PHY_MODE_QUARTER_RATE 0x00000040 /* Enable Quarter rat (test) */ - -/* - * PHY CCK transmit control register [5111+ (?)] - */ -#define AR5K_PHY_CCKTXCTL 0xa204 -#define AR5K_PHY_CCKTXCTL_WORLD 0x00000000 -#define AR5K_PHY_CCKTXCTL_JAPAN 0x00000010 -#define AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001 -#define AR5K_PHY_CCKTXCTK_DAC_SCALE 0x00000004 - -/* - * PHY CCK Cross-correlator Barker RSSI threshold register [5212+] - */ -#define AR5K_PHY_CCK_CROSSCORR 0xa208 -#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f -#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 - -/* Same address is used for antenna diversity activation */ -#define AR5K_PHY_FAST_ANT_DIV 0xa208 -#define AR5K_PHY_FAST_ANT_DIV_EN 0x00002000 - -/* - * PHY 2GHz gain register [5111+] - */ -#define AR5K_PHY_GAIN_2GHZ 0xa20c -#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 -#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18 -#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c - -#define AR5K_PHY_CCK_RX_CTL_4 0xa21c -#define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT 0x01f80000 -#define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S 19 - -#define AR5K_PHY_DAG_CCK_CTL 0xa228 -#define AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR 0x00000200 -#define AR5K_PHY_DAG_CCK_CTL_RSSI_THR 0x0001fc00 -#define AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S 10 - -#define AR5K_PHY_FAST_ADC 0xa24c - -#define AR5K_PHY_BLUETOOTH 0xa254 - -/* - * Transmit Power Control register - * [2413+] - */ -#define AR5K_PHY_TPC_RG1 0xa258 -#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000 -#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14 -#define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000 -#define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16 -#define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000 -#define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18 -#define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000 -#define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20 - -#define AR5K_PHY_TPC_RG5 0xa26C -#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F -#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S 0 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1 0x000003F0 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S 4 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2 0x0000FC00 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S 10 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3 0x003F0000 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000 -#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22 - -/* - * PHY PDADC Tx power table - */ -#define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280 -#define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2)) - -/* - * Platform registers for WiSoC - */ -#define AR5K_AR5312_RESET 0xbc003020 -#define AR5K_AR5312_RESET_BB0_COLD 0x00000004 -#define AR5K_AR5312_RESET_BB1_COLD 0x00000200 -#define AR5K_AR5312_RESET_WMAC0 0x00002000 -#define AR5K_AR5312_RESET_BB0_WARM 0x00004000 -#define AR5K_AR5312_RESET_WMAC1 0x00020000 -#define AR5K_AR5312_RESET_BB1_WARM 0x00040000 - -#define AR5K_AR5312_ENABLE 0xbc003080 -#define AR5K_AR5312_ENABLE_WLAN0 0x00000001 -#define AR5K_AR5312_ENABLE_WLAN1 0x00000008 - -#define AR5K_AR2315_RESET 0xb1000004 -#define AR5K_AR2315_RESET_WMAC 0x00000001 -#define AR5K_AR2315_RESET_BB_WARM 0x00000002 - -#define AR5K_AR2315_AHB_ARB_CTL 0xb1000008 -#define AR5K_AR2315_AHB_ARB_CTL_WLAN 0x00000002 - -#define AR5K_AR2315_BYTESWAP 0xb100000c -#define AR5K_AR2315_BYTESWAP_WMAC 0x00000002 diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/reset.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/reset.c deleted file mode 100644 index 200f165c..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/reset.c +++ /dev/null @@ -1,1402 +0,0 @@ -/* - * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> - * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu> - * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> - * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/****************************\ - Reset function and helpers -\****************************/ - -#include <asm/unaligned.h> - -#include <linux/pci.h> /* To determine if a card is pci-e */ -#include <linux/log2.h> -#include <linux/platform_device.h> -#include "ath5k.h" -#include "reg.h" -#include "debug.h" - - -/** - * DOC: Reset function and helpers - * - * Here we implement the main reset routine, used to bring the card - * to a working state and ready to receive. We also handle routines - * that don't fit on other places such as clock, sleep and power control - */ - - -/******************\ -* Helper functions * -\******************/ - -/** - * ath5k_hw_register_timeout() - Poll a register for a flag/field change - * @ah: The &struct ath5k_hw - * @reg: The register to read - * @flag: The flag/field to check on the register - * @val: The field value we expect (if we check a field) - * @is_set: Instead of checking if the flag got cleared, check if it got set - * - * Some registers contain flags that indicate that an operation is - * running. We use this function to poll these registers and check - * if these flags get cleared. We also use it to poll a register - * field (containing multiple flags) until it gets a specific value. - * - * Returns -EAGAIN if we exceeded AR5K_TUNE_REGISTER_TIMEOUT * 15us or 0 - */ -int -ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, - bool is_set) -{ - int i; - u32 data; - - for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { - data = ath5k_hw_reg_read(ah, reg); - if (is_set && (data & flag)) - break; - else if ((data & flag) == val) - break; - udelay(15); - } - - return (i <= 0) ? -EAGAIN : 0; -} - - -/*************************\ -* Clock related functions * -\*************************/ - -/** - * ath5k_hw_htoclock() - Translate usec to hw clock units - * @ah: The &struct ath5k_hw - * @usec: value in microseconds - * - * Translate usecs to hw clock units based on the current - * hw clock rate. - * - * Returns number of clock units - */ -unsigned int -ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) -{ - struct ath_common *common = ath5k_hw_common(ah); - return usec * common->clockrate; -} - -/** - * ath5k_hw_clocktoh() - Translate hw clock units to usec - * @ah: The &struct ath5k_hw - * @clock: value in hw clock units - * - * Translate hw clock units to usecs based on the current - * hw clock rate. - * - * Returns number of usecs - */ -unsigned int -ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) -{ - struct ath_common *common = ath5k_hw_common(ah); - return clock / common->clockrate; -} - -/** - * ath5k_hw_init_core_clock() - Initialize core clock - * @ah: The &struct ath5k_hw - * - * Initialize core clock parameters (usec, usec32, latencies etc), - * based on current bwmode and chipset properties. - */ -static void -ath5k_hw_init_core_clock(struct ath5k_hw *ah) -{ - struct ieee80211_channel *channel = ah->ah_current_channel; - struct ath_common *common = ath5k_hw_common(ah); - u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs; - - /* - * Set core clock frequency - */ - switch (channel->hw_value) { - case AR5K_MODE_11A: - clock = 40; - break; - case AR5K_MODE_11B: - clock = 22; - break; - case AR5K_MODE_11G: - default: - clock = 44; - break; - } - - /* Use clock multiplier for non-default - * bwmode */ - switch (ah->ah_bwmode) { - case AR5K_BWMODE_40MHZ: - clock *= 2; - break; - case AR5K_BWMODE_10MHZ: - clock /= 2; - break; - case AR5K_BWMODE_5MHZ: - clock /= 4; - break; - default: - break; - } - - common->clockrate = clock; - - /* - * Set USEC parameters - */ - /* Set USEC counter on PCU*/ - usec = clock - 1; - usec = AR5K_REG_SM(usec, AR5K_USEC_1); - - /* Set usec duration on DCU */ - if (ah->ah_version != AR5K_AR5210) - AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, - AR5K_DCU_GBL_IFS_MISC_USEC_DUR, - clock); - - /* Set 32MHz USEC counter */ - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF2413) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2316) || - (ah->ah_radio == AR5K_RF2317)) - /* Remain on 40MHz clock ? */ - sclock = 40 - 1; - else - sclock = 32 - 1; - sclock = AR5K_REG_SM(sclock, AR5K_USEC_32); - - /* - * Set tx/rx latencies - */ - usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211); - txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211); - rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); - - /* - * Set default Tx frame to Tx data start delay - */ - txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT; - - /* - * 5210 initvals don't include usec settings - * so we need to use magic values here for - * tx/rx latencies - */ - if (ah->ah_version == AR5K_AR5210) { - /* same for turbo */ - txlat = AR5K_INIT_TX_LATENCY_5210; - rxlat = AR5K_INIT_RX_LATENCY_5210; - } - - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { - /* 5311 has different tx/rx latency masks - * from 5211, since we deal 5311 the same - * as 5211 when setting initvals, shift - * values here to their proper locations - * - * Note: Initvals indicate tx/rx/ latencies - * are the same for turbo mode */ - txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210); - rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210); - } else - switch (ah->ah_bwmode) { - case AR5K_BWMODE_10MHZ: - txlat = AR5K_REG_SM(txlat * 2, - AR5K_USEC_TX_LATENCY_5211); - rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX, - AR5K_USEC_RX_LATENCY_5211); - txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ; - break; - case AR5K_BWMODE_5MHZ: - txlat = AR5K_REG_SM(txlat * 4, - AR5K_USEC_TX_LATENCY_5211); - rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX, - AR5K_USEC_RX_LATENCY_5211); - txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ; - break; - case AR5K_BWMODE_40MHZ: - txlat = AR5K_INIT_TX_LAT_MIN; - rxlat = AR5K_REG_SM(rxlat / 2, - AR5K_USEC_RX_LATENCY_5211); - txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT; - break; - default: - break; - } - - usec_reg = (usec | sclock | txlat | rxlat); - ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC); - - /* On 5112 set tx frame to tx data start delay */ - if (ah->ah_radio == AR5K_RF5112) { - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2, - AR5K_PHY_RF_CTL2_TXF2TXD_START, - txf2txs); - } -} - -/** - * ath5k_hw_set_sleep_clock() - Setup sleep clock operation - * @ah: The &struct ath5k_hw - * @enable: Enable sleep clock operation (false to disable) - * - * If there is an external 32KHz crystal available, use it - * as ref. clock instead of 32/40MHz clock and baseband clocks - * to save power during sleep or restore normal 32/40MHz - * operation. - * - * NOTE: When operating on 32KHz certain PHY registers (27 - 31, - * 123 - 127) require delay on access. - */ -static void -ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - u32 scal, spending, sclock; - - /* Only set 32KHz settings if we have an external - * 32KHz crystal present */ - if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) || - AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) && - enable) { - - /* 1 usec/cycle */ - AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1); - /* Set up tsf increment on each cycle */ - AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61); - - /* Set baseband sleep control registers - * and sleep control rate */ - ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2316) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) - spending = 0x14; - else - spending = 0x18; - ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { - ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT); - ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL); - ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK); - ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY); - AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02); - } else { - ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT); - ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL); - ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK); - ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY); - AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03); - } - - /* Enable sleep clock operation */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_EN); - - } else { - - /* Disable sleep clock operation and - * restore default parameters */ - AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_EN); - - AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, - AR5K_PCICFG_SLEEP_CLOCK_RATE, 0); - - /* Set DAC/ADC delays */ - ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); - ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); - - if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) - scal = AR5K_PHY_SCAL_32MHZ_2417; - else if (ee->ee_is_hb63) - scal = AR5K_PHY_SCAL_32MHZ_HB63; - else - scal = AR5K_PHY_SCAL_32MHZ; - ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); - - ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); - ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2316) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) - spending = 0x14; - else - spending = 0x18; - ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); - - /* Set up tsf increment on each cycle */ - AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); - - if ((ah->ah_radio == AR5K_RF5112) || - (ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2316) || - (ah->ah_radio == AR5K_RF2317)) - sclock = 40 - 1; - else - sclock = 32 - 1; - AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, sclock); - } -} - - -/*********************\ -* Reset/Sleep control * -\*********************/ - -/** - * ath5k_hw_nic_reset() - Reset the various chipset units - * @ah: The &struct ath5k_hw - * @val: Mask to indicate what units to reset - * - * To reset the various chipset units we need to write - * the mask to AR5K_RESET_CTL and poll the register until - * all flags are cleared. - * - * Returns 0 if we are O.K. or -EAGAIN (from athk5_hw_register_timeout) - */ -static int -ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) -{ - int ret; - u32 mask = val ? val : ~0U; - - /* Read-and-clear RX Descriptor Pointer*/ - ath5k_hw_reg_read(ah, AR5K_RXDP); - - /* - * Reset the device and wait until success - */ - ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL); - - /* Wait at least 128 PCI clocks */ - usleep_range(15, 20); - - if (ah->ah_version == AR5K_AR5210) { - val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA - | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; - mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA - | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; - } else { - val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; - mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; - } - - ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false); - - /* - * Reset configuration register (for hw byte-swap). Note that this - * is only set for big endian. We do the necessary magic in - * AR5K_INIT_CFG. - */ - if ((val & AR5K_RESET_CTL_PCU) == 0) - ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); - - return ret; -} - -/** - * ath5k_hw_wisoc_reset() - Reset AHB chipset - * @ah: The &struct ath5k_hw - * @flags: Mask to indicate what units to reset - * - * Same as ath5k_hw_nic_reset but for AHB based devices - * - * Returns 0 if we are O.K. or -EAGAIN (from athk5_hw_register_timeout) - */ -static int -ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags) -{ - u32 mask = flags ? flags : ~0U; - u32 __iomem *reg; - u32 regval; - u32 val = 0; - - /* ah->ah_mac_srev is not available at this point yet */ - if (ah->devid >= AR5K_SREV_AR2315_R6) { - reg = (u32 __iomem *) AR5K_AR2315_RESET; - if (mask & AR5K_RESET_CTL_PCU) - val |= AR5K_AR2315_RESET_WMAC; - if (mask & AR5K_RESET_CTL_BASEBAND) - val |= AR5K_AR2315_RESET_BB_WARM; - } else { - reg = (u32 __iomem *) AR5K_AR5312_RESET; - if (to_platform_device(ah->dev)->id == 0) { - if (mask & AR5K_RESET_CTL_PCU) - val |= AR5K_AR5312_RESET_WMAC0; - if (mask & AR5K_RESET_CTL_BASEBAND) - val |= AR5K_AR5312_RESET_BB0_COLD | - AR5K_AR5312_RESET_BB0_WARM; - } else { - if (mask & AR5K_RESET_CTL_PCU) - val |= AR5K_AR5312_RESET_WMAC1; - if (mask & AR5K_RESET_CTL_BASEBAND) - val |= AR5K_AR5312_RESET_BB1_COLD | - AR5K_AR5312_RESET_BB1_WARM; - } - } - - /* Put BB/MAC into reset */ - regval = ioread32(reg); - iowrite32(regval | val, reg); - regval = ioread32(reg); - usleep_range(100, 150); - - /* Bring BB/MAC out of reset */ - iowrite32(regval & ~val, reg); - regval = ioread32(reg); - - /* - * Reset configuration register (for hw byte-swap). Note that this - * is only set for big endian. We do the necessary magic in - * AR5K_INIT_CFG. - */ - if ((flags & AR5K_RESET_CTL_PCU) == 0) - ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); - - return 0; -} - -/** - * ath5k_hw_set_power_mode() - Set power mode - * @ah: The &struct ath5k_hw - * @mode: One of enum ath5k_power_mode - * @set_chip: Set to true to write sleep control register - * @sleep_duration: How much time the device is allowed to sleep - * when sleep logic is enabled (in 128 microsecond increments). - * - * This function is used to configure sleep policy and allowed - * sleep modes. For more information check out the sleep control - * register on reg.h and STA_ID1. - * - * Returns 0 on success, -EIO if chip didn't wake up or -EINVAL if an invalid - * mode is requested. - */ -static int -ath5k_hw_set_power_mode(struct ath5k_hw *ah, enum ath5k_power_mode mode, - bool set_chip, u16 sleep_duration) -{ - unsigned int i; - u32 staid, data; - - staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); - - switch (mode) { - case AR5K_PM_AUTO: - staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA; - /* fallthrough */ - case AR5K_PM_NETWORK_SLEEP: - if (set_chip) - ath5k_hw_reg_write(ah, - AR5K_SLEEP_CTL_SLE_ALLOW | - sleep_duration, - AR5K_SLEEP_CTL); - - staid |= AR5K_STA_ID1_PWR_SV; - break; - - case AR5K_PM_FULL_SLEEP: - if (set_chip) - ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP, - AR5K_SLEEP_CTL); - - staid |= AR5K_STA_ID1_PWR_SV; - break; - - case AR5K_PM_AWAKE: - - staid &= ~AR5K_STA_ID1_PWR_SV; - - if (!set_chip) - goto commit; - - data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); - - /* If card is down we 'll get 0xffff... so we - * need to clean this up before we write the register - */ - if (data & 0xffc00000) - data = 0; - else - /* Preserve sleep duration etc */ - data = data & ~AR5K_SLEEP_CTL_SLE; - - ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE, - AR5K_SLEEP_CTL); - usleep_range(15, 20); - - for (i = 200; i > 0; i--) { - /* Check if the chip did wake up */ - if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & - AR5K_PCICFG_SPWR_DN) == 0) - break; - - /* Wait a bit and retry */ - usleep_range(50, 75); - ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE, - AR5K_SLEEP_CTL); - } - - /* Fail if the chip didn't wake up */ - if (i == 0) - return -EIO; - - break; - - default: - return -EINVAL; - } - -commit: - ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1); - - return 0; -} - -/** - * ath5k_hw_on_hold() - Put device on hold - * @ah: The &struct ath5k_hw - * - * Put MAC and Baseband on warm reset and keep that state - * (don't clean sleep control register). After this MAC - * and Baseband are disabled and a full reset is needed - * to come back. This way we save as much power as possible - * without putting the card on full sleep. - * - * Returns 0 on success or -EIO on error - */ -int -ath5k_hw_on_hold(struct ath5k_hw *ah) -{ - struct pci_dev *pdev = ah->pdev; - u32 bus_flags; - int ret; - - if (ath5k_get_bus_type(ah) == ATH_AHB) - return 0; - - /* Make sure device is awake */ - ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0); - if (ret) { - ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n"); - return ret; - } - - /* - * Put chipset on warm reset... - * - * Note: putting PCI core on warm reset on PCI-E cards - * results card to hang and always return 0xffff... so - * we ignore that flag for PCI-E cards. On PCI cards - * this flag gets cleared after 64 PCI clocks. - */ - bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI; - - if (ah->ah_version == AR5K_AR5210) { - ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA | - AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); - usleep_range(2000, 2500); - } else { - ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_BASEBAND | bus_flags); - } - - if (ret) { - ATH5K_ERR(ah, "failed to put device on warm reset\n"); - return -EIO; - } - - /* ...wakeup again!*/ - ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0); - if (ret) { - ATH5K_ERR(ah, "failed to put device on hold\n"); - return ret; - } - - return ret; -} - -/** - * ath5k_hw_nic_wakeup() - Force card out of sleep - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * Bring up MAC + PHY Chips and program PLL - * NOTE: Channel is NULL for the initial wakeup. - * - * Returns 0 on success, -EIO on hw failure or -EINVAL for false channel infos - */ -int -ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel) -{ - struct pci_dev *pdev = ah->pdev; - u32 turbo, mode, clock, bus_flags; - int ret; - - turbo = 0; - mode = 0; - clock = 0; - - if ((ath5k_get_bus_type(ah) != ATH_AHB) || channel) { - /* Wakeup the device */ - ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0); - if (ret) { - ATH5K_ERR(ah, "failed to wakeup the MAC Chip\n"); - return ret; - } - } - - /* - * Put chipset on warm reset... - * - * Note: putting PCI core on warm reset on PCI-E cards - * results card to hang and always return 0xffff... so - * we ignore that flag for PCI-E cards. On PCI cards - * this flag gets cleared after 64 PCI clocks. - */ - bus_flags = (pdev && pci_is_pcie(pdev)) ? 0 : AR5K_RESET_CTL_PCI; - - if (ah->ah_version == AR5K_AR5210) { - ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA | - AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); - usleep_range(2000, 2500); - } else { - if (ath5k_get_bus_type(ah) == ATH_AHB) - ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_BASEBAND); - else - ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_BASEBAND | bus_flags); - } - - if (ret) { - ATH5K_ERR(ah, "failed to reset the MAC Chip\n"); - return -EIO; - } - - /* ...wakeup again!...*/ - ret = ath5k_hw_set_power_mode(ah, AR5K_PM_AWAKE, true, 0); - if (ret) { - ATH5K_ERR(ah, "failed to resume the MAC Chip\n"); - return ret; - } - - /* ...reset configuration register on Wisoc ... - * ...clear reset control register and pull device out of - * warm reset on others */ - if (ath5k_get_bus_type(ah) == ATH_AHB) - ret = ath5k_hw_wisoc_reset(ah, 0); - else - ret = ath5k_hw_nic_reset(ah, 0); - - if (ret) { - ATH5K_ERR(ah, "failed to warm reset the MAC Chip\n"); - return -EIO; - } - - /* On initialization skip PLL programming since we don't have - * a channel / mode set yet */ - if (!channel) - return 0; - - if (ah->ah_version != AR5K_AR5210) { - /* - * Get channel mode flags - */ - - if (ah->ah_radio >= AR5K_RF5112) { - mode = AR5K_PHY_MODE_RAD_RF5112; - clock = AR5K_PHY_PLL_RF5112; - } else { - mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/ - clock = AR5K_PHY_PLL_RF5111; /*Zero*/ - } - - if (channel->band == IEEE80211_BAND_2GHZ) { - mode |= AR5K_PHY_MODE_FREQ_2GHZ; - clock |= AR5K_PHY_PLL_44MHZ; - - if (channel->hw_value == AR5K_MODE_11B) { - mode |= AR5K_PHY_MODE_MOD_CCK; - } else { - /* XXX Dynamic OFDM/CCK is not supported by the - * AR5211 so we set MOD_OFDM for plain g (no - * CCK headers) operation. We need to test - * this, 5211 might support ofdm-only g after - * all, there are also initial register values - * in the code for g mode (see initvals.c). - */ - if (ah->ah_version == AR5K_AR5211) - mode |= AR5K_PHY_MODE_MOD_OFDM; - else - mode |= AR5K_PHY_MODE_MOD_DYN; - } - } else if (channel->band == IEEE80211_BAND_5GHZ) { - mode |= (AR5K_PHY_MODE_FREQ_5GHZ | - AR5K_PHY_MODE_MOD_OFDM); - - /* Different PLL setting for 5413 */ - if (ah->ah_radio == AR5K_RF5413) - clock = AR5K_PHY_PLL_40MHZ_5413; - else - clock |= AR5K_PHY_PLL_40MHZ; - } else { - ATH5K_ERR(ah, "invalid radio frequency mode\n"); - return -EINVAL; - } - - /*XXX: Can bwmode be used with dynamic mode ? - * (I don't think it supports 44MHz) */ - /* On 2425 initvals TURBO_SHORT is not present */ - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { - turbo = AR5K_PHY_TURBO_MODE | - (ah->ah_radio == AR5K_RF2425) ? 0 : - AR5K_PHY_TURBO_SHORT; - } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { - if (ah->ah_radio == AR5K_RF5413) { - mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? - AR5K_PHY_MODE_HALF_RATE : - AR5K_PHY_MODE_QUARTER_RATE; - } else if (ah->ah_version == AR5K_AR5212) { - clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? - AR5K_PHY_PLL_HALF_RATE : - AR5K_PHY_PLL_QUARTER_RATE; - } - } - - } else { /* Reset the device */ - - /* ...enable Atheros turbo mode if requested */ - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) - ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, - AR5K_PHY_TURBO); - } - - if (ah->ah_version != AR5K_AR5210) { - - /* ...update PLL if needed */ - if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) { - ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); - usleep_range(300, 350); - } - - /* ...set the PHY operating mode */ - ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); - ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); - } - - return 0; -} - - -/**************************************\ -* Post-initvals register modifications * -\**************************************/ - -/** - * ath5k_hw_tweak_initval_settings() - Tweak initial settings - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * Some settings are not handled on initvals, e.g. bwmode - * settings, some phy settings, workarounds etc that in general - * don't fit anywhere else or are too small to introduce a separate - * function for each one. So we have this function to handle - * them all during reset and complete card's initialization. - */ -static void -ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - if (ah->ah_version == AR5K_AR5212 && - ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { - - /* Setup ADC control */ - ath5k_hw_reg_write(ah, - (AR5K_REG_SM(2, - AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) | - AR5K_REG_SM(2, - AR5K_PHY_ADC_CTL_INBUFGAIN_ON) | - AR5K_PHY_ADC_CTL_PWD_DAC_OFF | - AR5K_PHY_ADC_CTL_PWD_ADC_OFF), - AR5K_PHY_ADC_CTL); - - - - /* Disable barker RSSI threshold */ - AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, - AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR); - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, - AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2); - - /* Set the mute mask */ - ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); - } - - /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */ - if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B) - ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH); - - /* Enable DCU double buffering */ - if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B) - AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, - AR5K_TXCFG_DCU_DBL_BUF_DIS); - - /* Set fast ADC */ - if ((ah->ah_radio == AR5K_RF5413) || - (ah->ah_radio == AR5K_RF2317) || - (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { - u32 fast_adc = true; - - if (channel->center_freq == 2462 || - channel->center_freq == 2467) - fast_adc = 0; - - /* Only update if needed */ - if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc) - ath5k_hw_reg_write(ah, fast_adc, - AR5K_PHY_FAST_ADC); - } - - /* Fix for first revision of the RF5112 RF chipset */ - if (ah->ah_radio == AR5K_RF5112 && - ah->ah_radio_5ghz_revision < - AR5K_SREV_RAD_5112A) { - u32 data; - ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, - AR5K_PHY_CCKTXCTL); - if (channel->band == IEEE80211_BAND_5GHZ) - data = 0xffb81020; - else - data = 0xffb80d20; - ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); - } - - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { - /* Clear QCU/DCU clock gating register */ - ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); - /* Set DAC/ADC delays */ - ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311, - AR5K_PHY_SCAL); - /* Enable PCU FIFO corruption ECO */ - AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_ECO_ENABLE); - } - - if (ah->ah_bwmode) { - /* Increase PHY switch and AGC settling time - * on turbo mode (ath5k_hw_commit_eeprom_settings - * will override settling time if available) */ - if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, - AR5K_PHY_SETTLING_AGC, - AR5K_AGC_SETTLING_TURBO); - - /* XXX: Initvals indicate we only increase - * switch time on AR5212, 5211 and 5210 - * only change agc time (bug?) */ - if (ah->ah_version == AR5K_AR5212) - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, - AR5K_PHY_SETTLING_SWITCH, - AR5K_SWITCH_SETTLING_TURBO); - - if (ah->ah_version == AR5K_AR5210) { - /* Set Frame Control Register */ - ath5k_hw_reg_write(ah, - (AR5K_PHY_FRAME_CTL_INI | - AR5K_PHY_TURBO_MODE | - AR5K_PHY_TURBO_SHORT | 0x2020), - AR5K_PHY_FRAME_CTL_5210); - } - /* On 5413 PHY force window length for half/quarter rate*/ - } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) && - (ah->ah_mac_srev <= AR5K_SREV_AR5414)) { - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211, - AR5K_PHY_FRAME_CTL_WIN_LEN, - 3); - } - } else if (ah->ah_version == AR5K_AR5210) { - /* Set Frame Control Register for normal operation */ - ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020), - AR5K_PHY_FRAME_CTL_5210); - } -} - -/** - * ath5k_hw_commit_eeprom_settings() - Commit settings from EEPROM - * @ah: The &struct ath5k_hw - * @channel: The &struct ieee80211_channel - * - * Use settings stored on EEPROM to properly initialize the card - * based on various infos and per-mode calibration data. - */ -static void -ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, - struct ieee80211_channel *channel) -{ - struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; - s16 cck_ofdm_pwr_delta; - u8 ee_mode; - - /* TODO: Add support for AR5210 EEPROM */ - if (ah->ah_version == AR5K_AR5210) - return; - - ee_mode = ath5k_eeprom_mode_from_channel(channel); - - /* Adjust power delta for channel 14 */ - if (channel->center_freq == 2484) - cck_ofdm_pwr_delta = - ((ee->ee_cck_ofdm_power_delta - - ee->ee_scaled_cck_delta) * 2) / 10; - else - cck_ofdm_pwr_delta = - (ee->ee_cck_ofdm_power_delta * 2) / 10; - - /* Set CCK to OFDM power delta on tx power - * adjustment register */ - if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { - if (channel->hw_value == AR5K_MODE_11G) - ath5k_hw_reg_write(ah, - AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1), - AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) | - AR5K_REG_SM((cck_ofdm_pwr_delta * -1), - AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX), - AR5K_PHY_TX_PWR_ADJ); - else - ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ); - } else { - /* For older revs we scale power on sw during tx power - * setup */ - ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta; - ah->ah_txpower.txp_cck_ofdm_gainf_delta = - ee->ee_cck_ofdm_gain_delta; - } - - /* XXX: necessary here? is called from ath5k_hw_set_antenna_mode() - * too */ - ath5k_hw_set_antenna_switch(ah, ee_mode); - - /* Noise floor threshold */ - ath5k_hw_reg_write(ah, - AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), - AR5K_PHY_NFTHRES); - - if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) && - (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) { - /* Switch settling time (Turbo) */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, - AR5K_PHY_SETTLING_SWITCH, - ee->ee_switch_settling_turbo[ee_mode]); - - /* Tx/Rx attenuation (Turbo) */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, - AR5K_PHY_GAIN_TXRX_ATTEN, - ee->ee_atn_tx_rx_turbo[ee_mode]); - - /* ADC/PGA desired size (Turbo) */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, - AR5K_PHY_DESIRED_SIZE_ADC, - ee->ee_adc_desired_size_turbo[ee_mode]); - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, - AR5K_PHY_DESIRED_SIZE_PGA, - ee->ee_pga_desired_size_turbo[ee_mode]); - - /* Tx/Rx margin (Turbo) */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, - AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, - ee->ee_margin_tx_rx_turbo[ee_mode]); - - } else { - /* Switch settling time */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, - AR5K_PHY_SETTLING_SWITCH, - ee->ee_switch_settling[ee_mode]); - - /* Tx/Rx attenuation */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, - AR5K_PHY_GAIN_TXRX_ATTEN, - ee->ee_atn_tx_rx[ee_mode]); - - /* ADC/PGA desired size */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, - AR5K_PHY_DESIRED_SIZE_ADC, - ee->ee_adc_desired_size[ee_mode]); - - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, - AR5K_PHY_DESIRED_SIZE_PGA, - ee->ee_pga_desired_size[ee_mode]); - - /* Tx/Rx margin */ - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, - AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, - ee->ee_margin_tx_rx[ee_mode]); - } - - /* XPA delays */ - ath5k_hw_reg_write(ah, - (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | - (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | - (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | - (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); - - /* XLNA delay */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3, - AR5K_PHY_RF_CTL3_TXE2XLNA_ON, - ee->ee_tx_end2xlna_enable[ee_mode]); - - /* Thresh64 (ANI) */ - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF, - AR5K_PHY_NF_THRESH62, - ee->ee_thr_62[ee_mode]); - - /* False detect backoff for channels - * that have spur noise. Write the new - * cyclic power RSSI threshold. */ - if (ath5k_hw_chan_has_spur_noise(ah, channel)) - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, - AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, - AR5K_INIT_CYCRSSI_THR1 + - ee->ee_false_detect[ee_mode]); - else - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, - AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, - AR5K_INIT_CYCRSSI_THR1); - - /* I/Q correction (set enable bit last to match HAL sources) */ - /* TODO: Per channel i/q infos ? */ - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_I_COFF, - ee->ee_i_cal[ee_mode]); - AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_Q_Q_COFF, - ee->ee_q_cal[ee_mode]); - AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE); - } - - /* Heavy clipping -disable for now */ - if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) - ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); -} - - -/*********************\ -* Main reset function * -\*********************/ - -/** - * ath5k_hw_reset() - The main reset function - * @ah: The &struct ath5k_hw - * @op_mode: One of enum nl80211_iftype - * @channel: The &struct ieee80211_channel - * @fast: Enable fast channel switching - * @skip_pcu: Skip pcu initialization - * - * This is the function we call each time we want to (re)initialize the - * card and pass new settings to hw. We also call it when hw runs into - * trouble to make it come back to a working state. - * - * Returns 0 on success, -EINVAL on false op_mode or channel infos, or -EIO - * on failure. - */ -int -ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, - struct ieee80211_channel *channel, bool fast, bool skip_pcu) -{ - u32 s_seq[10], s_led[3], tsf_up, tsf_lo; - u8 mode; - int i, ret; - - tsf_up = 0; - tsf_lo = 0; - mode = 0; - - /* - * Sanity check for fast flag - * Fast channel change only available - * on AR2413/AR5413. - */ - if (fast && (ah->ah_radio != AR5K_RF2413) && - (ah->ah_radio != AR5K_RF5413)) - fast = false; - - /* Disable sleep clock operation - * to avoid register access delay on certain - * PHY registers */ - if (ah->ah_version == AR5K_AR5212) - ath5k_hw_set_sleep_clock(ah, false); - - /* - * Stop PCU - */ - ath5k_hw_stop_rx_pcu(ah); - - /* - * Stop DMA - * - * Note: If DMA didn't stop continue - * since only a reset will fix it. - */ - ret = ath5k_hw_dma_stop(ah); - - /* RF Bus grant won't work if we have pending - * frames */ - if (ret && fast) { - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "DMA didn't stop, falling back to normal reset\n"); - fast = false; - /* Non fatal, just continue with - * normal reset */ - ret = 0; - } - - mode = channel->hw_value; - switch (mode) { - case AR5K_MODE_11A: - break; - case AR5K_MODE_11G: - if (ah->ah_version <= AR5K_AR5211) { - ATH5K_ERR(ah, - "G mode not available on 5210/5211"); - return -EINVAL; - } - break; - case AR5K_MODE_11B: - if (ah->ah_version < AR5K_AR5211) { - ATH5K_ERR(ah, - "B mode not available on 5210"); - return -EINVAL; - } - break; - default: - ATH5K_ERR(ah, - "invalid channel: %d\n", channel->center_freq); - return -EINVAL; - } - - /* - * If driver requested fast channel change and DMA has stopped - * go on. If it fails continue with a normal reset. - */ - if (fast) { - ret = ath5k_hw_phy_init(ah, channel, mode, true); - if (ret) { - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "fast chan change failed, falling back to normal reset\n"); - /* Non fatal, can happen eg. - * on mode change */ - ret = 0; - } else { - ATH5K_DBG(ah, ATH5K_DEBUG_RESET, - "fast chan change successful\n"); - return 0; - } - } - - /* - * Save some registers before a reset - */ - if (ah->ah_version != AR5K_AR5210) { - /* - * Save frame sequence count - * For revs. after Oahu, only save - * seq num for DCU 0 (Global seq num) - */ - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { - - for (i = 0; i < 10; i++) - s_seq[i] = ath5k_hw_reg_read(ah, - AR5K_QUEUE_DCU_SEQNUM(i)); - - } else { - s_seq[0] = ath5k_hw_reg_read(ah, - AR5K_QUEUE_DCU_SEQNUM(0)); - } - - /* TSF accelerates on AR5211 during reset - * As a workaround save it here and restore - * it later so that it's back in time after - * reset. This way it'll get re-synced on the - * next beacon without breaking ad-hoc. - * - * On AR5212 TSF is almost preserved across a - * reset so it stays back in time anyway and - * we don't have to save/restore it. - * - * XXX: Since this breaks power saving we have - * to disable power saving until we receive the - * next beacon, so we can resync beacon timers */ - if (ah->ah_version == AR5K_AR5211) { - tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32); - tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32); - } - } - - - /*GPIOs*/ - s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & - AR5K_PCICFG_LEDSTATE; - s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); - s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); - - - /* - * Since we are going to write rf buffer - * check if we have any pending gain_F - * optimization settings - */ - if (ah->ah_version == AR5K_AR5212 && - (ah->ah_radio <= AR5K_RF5112)) { - if (!fast && ah->ah_rf_banks != NULL) - ath5k_hw_gainf_calibrate(ah); - } - - /* Wakeup the device */ - ret = ath5k_hw_nic_wakeup(ah, channel); - if (ret) - return ret; - - /* PHY access enable */ - if (ah->ah_mac_srev >= AR5K_SREV_AR5211) - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); - else - ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40, - AR5K_PHY(0)); - - /* Write initial settings */ - ret = ath5k_hw_write_initvals(ah, mode, skip_pcu); - if (ret) - return ret; - - /* Initialize core clock settings */ - ath5k_hw_init_core_clock(ah); - - /* - * Tweak initval settings for revised - * chipsets and add some more config - * bits - */ - ath5k_hw_tweak_initval_settings(ah, channel); - - /* Commit values from EEPROM */ - ath5k_hw_commit_eeprom_settings(ah, channel); - - - /* - * Restore saved values - */ - - /* Seqnum, TSF */ - if (ah->ah_version != AR5K_AR5210) { - if (ah->ah_mac_srev < AR5K_SREV_AR5211) { - for (i = 0; i < 10; i++) - ath5k_hw_reg_write(ah, s_seq[i], - AR5K_QUEUE_DCU_SEQNUM(i)); - } else { - ath5k_hw_reg_write(ah, s_seq[0], - AR5K_QUEUE_DCU_SEQNUM(0)); - } - - if (ah->ah_version == AR5K_AR5211) { - ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32); - ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); - } - } - - /* Ledstate */ - AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); - - /* Gpio settings */ - ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); - ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); - - /* - * Initialize PCU - */ - ath5k_hw_pcu_init(ah, op_mode); - - /* - * Initialize PHY - */ - ret = ath5k_hw_phy_init(ah, channel, mode, false); - if (ret) { - ATH5K_ERR(ah, - "failed to initialize PHY (%i) !\n", ret); - return ret; - } - - /* - * Configure QCUs/DCUs - */ - ret = ath5k_hw_init_queues(ah); - if (ret) - return ret; - - - /* - * Initialize DMA/Interrupts - */ - ath5k_hw_dma_init(ah); - - - /* - * Enable 32KHz clock function for AR5212+ chips - * Set clocks to 32KHz operation and use an - * external 32KHz crystal when sleeping if one - * exists. - * Disabled by default because it is also disabled in - * other drivers and it is known to cause stability - * issues on some devices - */ - if (ah->ah_use_32khz_clock && ah->ah_version == AR5K_AR5212 && - op_mode != NL80211_IFTYPE_AP) - ath5k_hw_set_sleep_clock(ah, true); - - /* - * Disable beacons and reset the TSF - */ - AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE); - ath5k_hw_reset_tsf(ah); - return 0; -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfbuffer.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfbuffer.h deleted file mode 100644 index aed34d99..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ /dev/null @@ -1,853 +0,0 @@ -/* - * RF Buffer handling functions - * - * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - - -/** - * DOC: RF Buffer registers - * - * There are some special registers on the RF chip - * that control various operation settings related mostly to - * the analog parts (channel, gain adjustment etc). - * - * We don't write on those registers directly but - * we send a data packet on the chip, using a special register, - * that holds all the settings we need. After we've sent the - * data packet, we write on another special register to notify hw - * to apply the settings. This is done so that control registers - * can be dynamically programmed during operation and the settings - * are applied faster on the hw. - * - * We call each data packet an "RF Bank" and all the data we write - * (all RF Banks) "RF Buffer". This file holds initial RF Buffer - * data for the different RF chips, and various info to match RF - * Buffer offsets with specific RF registers so that we can access - * them. We tweak these settings on rfregs_init function. - * - * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer - * registers and control registers): - * - * http://www.google.com/patents?id=qNURAAAAEBAJ - */ - - -/** - * struct ath5k_ini_rfbuffer - Initial RF Buffer settings - * @rfb_bank: RF Bank number - * @rfb_ctrl_register: RF Buffer control register - * @rfb_mode_data: RF Buffer data for each mode - * - * Struct to hold default mode specific RF - * register values (RF Banks) for each chip. - */ -struct ath5k_ini_rfbuffer { - u8 rfb_bank; - u16 rfb_ctrl_register; - u32 rfb_mode_data[3]; -}; - -/** - * struct ath5k_rfb_field - An RF Buffer field (register/value) - * @len: Field length - * @pos: Offset on the raw packet - * @col: Used for shifting - * - * Struct to hold RF Buffer field - * infos used to access certain RF - * analog registers - */ -struct ath5k_rfb_field { - u8 len; - u16 pos; - u8 col; -}; - -/** - * struct ath5k_rf_reg - RF analog register definition - * @bank: RF Buffer Bank number - * @index: Register's index on ath5k_rf_regx_idx - * @field: The &struct ath5k_rfb_field - * - * We use this struct to define the set of RF registers - * on each chip that we want to tweak. Some RF registers - * are common between different chip versions so this saves - * us space and complexity because we can refer to an rf - * register by it's index no matter what chip we work with - * as long as it has that register. - */ -struct ath5k_rf_reg { - u8 bank; - u8 index; - struct ath5k_rfb_field field; -}; - -/** - * enum ath5k_rf_regs_idx - Map RF registers to indexes - * - * We do this to handle common bits and make our - * life easier by using an index for each register - * instead of a full rfb_field - */ -enum ath5k_rf_regs_idx { - /* BANK 2 */ - AR5K_RF_TURBO = 0, - /* BANK 6 */ - AR5K_RF_OB_2GHZ, - AR5K_RF_OB_5GHZ, - AR5K_RF_DB_2GHZ, - AR5K_RF_DB_5GHZ, - AR5K_RF_FIXED_BIAS_A, - AR5K_RF_FIXED_BIAS_B, - AR5K_RF_PWD_XPD, - AR5K_RF_XPD_SEL, - AR5K_RF_XPD_GAIN, - AR5K_RF_PD_GAIN_LO, - AR5K_RF_PD_GAIN_HI, - AR5K_RF_HIGH_VC_CP, - AR5K_RF_MID_VC_CP, - AR5K_RF_LOW_VC_CP, - AR5K_RF_PUSH_UP, - AR5K_RF_PAD2GND, - AR5K_RF_XB2_LVL, - AR5K_RF_XB5_LVL, - AR5K_RF_PWD_ICLOBUF_2G, - AR5K_RF_PWD_84, - AR5K_RF_PWD_90, - AR5K_RF_PWD_130, - AR5K_RF_PWD_131, - AR5K_RF_PWD_132, - AR5K_RF_PWD_136, - AR5K_RF_PWD_137, - AR5K_RF_PWD_138, - AR5K_RF_PWD_166, - AR5K_RF_PWD_167, - AR5K_RF_DERBY_CHAN_SEL_MODE, - /* BANK 7 */ - AR5K_RF_GAIN_I, - AR5K_RF_PLO_SEL, - AR5K_RF_RFGAIN_SEL, - AR5K_RF_RFGAIN_STEP, - AR5K_RF_WAIT_S, - AR5K_RF_WAIT_I, - AR5K_RF_MAX_TIME, - AR5K_RF_MIXVGA_OVR, - AR5K_RF_MIXGAIN_OVR, - AR5K_RF_MIXGAIN_STEP, - AR5K_RF_PD_DELAY_A, - AR5K_RF_PD_DELAY_B, - AR5K_RF_PD_DELAY_XR, - AR5K_RF_PD_PERIOD_A, - AR5K_RF_PD_PERIOD_B, - AR5K_RF_PD_PERIOD_XR, -}; - - -/*******************\ -* RF5111 (Sombrero) * -\*******************/ - -/* BANK 2 len pos col */ -#define AR5K_RF5111_RF_TURBO { 1, 3, 0 } - -/* BANK 6 len pos col */ -#define AR5K_RF5111_OB_2GHZ { 3, 119, 0 } -#define AR5K_RF5111_DB_2GHZ { 3, 122, 0 } - -#define AR5K_RF5111_OB_5GHZ { 3, 104, 0 } -#define AR5K_RF5111_DB_5GHZ { 3, 107, 0 } - -#define AR5K_RF5111_PWD_XPD { 1, 95, 0 } -#define AR5K_RF5111_XPD_GAIN { 4, 96, 0 } - -/* Access to PWD registers */ -#define AR5K_RF5111_PWD(_n) { 1, (135 - _n), 3 } - -/* BANK 7 len pos col */ -#define AR5K_RF5111_GAIN_I { 6, 29, 0 } -#define AR5K_RF5111_PLO_SEL { 1, 4, 0 } -#define AR5K_RF5111_RFGAIN_SEL { 1, 36, 0 } -#define AR5K_RF5111_RFGAIN_STEP { 6, 37, 0 } -/* Only on AR5212 BaseBand and up */ -#define AR5K_RF5111_WAIT_S { 5, 19, 0 } -#define AR5K_RF5111_WAIT_I { 5, 24, 0 } -#define AR5K_RF5111_MAX_TIME { 2, 49, 0 } - -static const struct ath5k_rf_reg rf_regs_5111[] = { - {2, AR5K_RF_TURBO, AR5K_RF5111_RF_TURBO}, - {6, AR5K_RF_OB_2GHZ, AR5K_RF5111_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF5111_DB_2GHZ}, - {6, AR5K_RF_OB_5GHZ, AR5K_RF5111_OB_5GHZ}, - {6, AR5K_RF_DB_5GHZ, AR5K_RF5111_DB_5GHZ}, - {6, AR5K_RF_PWD_XPD, AR5K_RF5111_PWD_XPD}, - {6, AR5K_RF_XPD_GAIN, AR5K_RF5111_XPD_GAIN}, - {6, AR5K_RF_PWD_84, AR5K_RF5111_PWD(84)}, - {6, AR5K_RF_PWD_90, AR5K_RF5111_PWD(90)}, - {7, AR5K_RF_GAIN_I, AR5K_RF5111_GAIN_I}, - {7, AR5K_RF_PLO_SEL, AR5K_RF5111_PLO_SEL}, - {7, AR5K_RF_RFGAIN_SEL, AR5K_RF5111_RFGAIN_SEL}, - {7, AR5K_RF_RFGAIN_STEP, AR5K_RF5111_RFGAIN_STEP}, - {7, AR5K_RF_WAIT_S, AR5K_RF5111_WAIT_S}, - {7, AR5K_RF_WAIT_I, AR5K_RF5111_WAIT_I}, - {7, AR5K_RF_MAX_TIME, AR5K_RF5111_MAX_TIME} -}; - -/* Default mode specific settings */ -static const struct ath5k_ini_rfbuffer rfb_5111[] = { - /* BANK / C.R. A/XR B G */ - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00380000, 0x00380000, 0x00380000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 0, 0x989c, { 0x00000000, 0x000000c0, 0x00000080 } }, - { 0, 0x989c, { 0x000400f9, 0x000400ff, 0x000400fd } }, - { 0, 0x98d4, { 0x00000000, 0x00000004, 0x00000004 } }, - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d4, { 0x00000010, 0x00000010, 0x00000010 } }, - { 3, 0x98d8, { 0x00601068, 0x00601068, 0x00601068 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, { 0x04000000, 0x04000000, 0x04000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x0a000000, 0x00000000 } }, - { 6, 0x989c, { 0x003800c0, 0x023800c0, 0x003800c0 } }, - { 6, 0x989c, { 0x00020006, 0x00000006, 0x00020006 } }, - { 6, 0x989c, { 0x00000089, 0x00000089, 0x00000089 } }, - { 6, 0x989c, { 0x000000a0, 0x000000a0, 0x000000a0 } }, - { 6, 0x989c, { 0x00040007, 0x00040007, 0x00040007 } }, - { 6, 0x98d4, { 0x0000001a, 0x0000001a, 0x0000001a } }, - { 7, 0x989c, { 0x00000040, 0x00000040, 0x00000040 } }, - { 7, 0x989c, { 0x00000010, 0x00000010, 0x00000010 } }, - { 7, 0x989c, { 0x00000008, 0x00000008, 0x00000008 } }, - { 7, 0x989c, { 0x0000004f, 0x0000004f, 0x0000004f } }, - { 7, 0x989c, { 0x000000f1, 0x00000061, 0x000000f1 } }, - { 7, 0x989c, { 0x0000904f, 0x0000904c, 0x0000904f } }, - { 7, 0x989c, { 0x0000125a, 0x0000129a, 0x0000125a } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000f, 0x0000000e } }, -}; - - - -/***********************\ -* RF5112/RF2112 (Derby) * -\***********************/ - -/* BANK 2 (Common) len pos col */ -#define AR5K_RF5112X_RF_TURBO { 1, 1, 2 } - -/* BANK 7 (Common) len pos col */ -#define AR5K_RF5112X_GAIN_I { 6, 14, 0 } -#define AR5K_RF5112X_MIXVGA_OVR { 1, 36, 0 } -#define AR5K_RF5112X_MIXGAIN_OVR { 2, 37, 0 } -#define AR5K_RF5112X_MIXGAIN_STEP { 4, 32, 0 } -#define AR5K_RF5112X_PD_DELAY_A { 4, 58, 0 } -#define AR5K_RF5112X_PD_DELAY_B { 4, 62, 0 } -#define AR5K_RF5112X_PD_DELAY_XR { 4, 66, 0 } -#define AR5K_RF5112X_PD_PERIOD_A { 4, 70, 0 } -#define AR5K_RF5112X_PD_PERIOD_B { 4, 74, 0 } -#define AR5K_RF5112X_PD_PERIOD_XR { 4, 78, 0 } - -/* RFX112 (Derby 1) */ - -/* BANK 6 len pos col */ -#define AR5K_RF5112_OB_2GHZ { 3, 269, 0 } -#define AR5K_RF5112_DB_2GHZ { 3, 272, 0 } - -#define AR5K_RF5112_OB_5GHZ { 3, 261, 0 } -#define AR5K_RF5112_DB_5GHZ { 3, 264, 0 } - -#define AR5K_RF5112_FIXED_BIAS_A { 1, 260, 0 } -#define AR5K_RF5112_FIXED_BIAS_B { 1, 259, 0 } - -#define AR5K_RF5112_XPD_SEL { 1, 284, 0 } -#define AR5K_RF5112_XPD_GAIN { 2, 252, 0 } - -/* Access to PWD registers */ -#define AR5K_RF5112_PWD(_n) { 1, (302 - _n), 3 } - -static const struct ath5k_rf_reg rf_regs_5112[] = { - {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO}, - {6, AR5K_RF_OB_2GHZ, AR5K_RF5112_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF5112_DB_2GHZ}, - {6, AR5K_RF_OB_5GHZ, AR5K_RF5112_OB_5GHZ}, - {6, AR5K_RF_DB_5GHZ, AR5K_RF5112_DB_5GHZ}, - {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112_FIXED_BIAS_A}, - {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112_FIXED_BIAS_B}, - {6, AR5K_RF_XPD_SEL, AR5K_RF5112_XPD_SEL}, - {6, AR5K_RF_XPD_GAIN, AR5K_RF5112_XPD_GAIN}, - {6, AR5K_RF_PWD_130, AR5K_RF5112_PWD(130)}, - {6, AR5K_RF_PWD_131, AR5K_RF5112_PWD(131)}, - {6, AR5K_RF_PWD_132, AR5K_RF5112_PWD(132)}, - {6, AR5K_RF_PWD_136, AR5K_RF5112_PWD(136)}, - {6, AR5K_RF_PWD_137, AR5K_RF5112_PWD(137)}, - {6, AR5K_RF_PWD_138, AR5K_RF5112_PWD(138)}, - {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, - {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR}, - {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, - {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP}, - {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, - {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, - {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, - {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A}, - {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B}, - {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR}, -}; - -/* Default mode specific settings */ -static const struct ath5k_ini_rfbuffer rfb_5112[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } }, - { 3, 0x98dc, { 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0 } }, - { 6, 0x989c, { 0x00a00000, 0x00a00000, 0x00a00000 } }, - { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00660000, 0x00660000, 0x00660000 } }, - { 6, 0x989c, { 0x00db0000, 0x00db0000, 0x00db0000 } }, - { 6, 0x989c, { 0x00f10000, 0x00f10000, 0x00f10000 } }, - { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } }, - { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } }, - { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x008b0000, 0x008b0000, 0x008b0000 } }, - { 6, 0x989c, { 0x00600000, 0x00600000, 0x00600000 } }, - { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } }, - { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } }, - { 6, 0x989c, { 0x00640000, 0x00640000, 0x00640000 } }, - { 6, 0x989c, { 0x00200000, 0x00200000, 0x00200000 } }, - { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } }, - { 6, 0x989c, { 0x00250000, 0x00250000, 0x00250000 } }, - { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } }, - { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } }, - { 6, 0x989c, { 0x00510000, 0x00510000, 0x00510000 } }, - { 6, 0x989c, { 0x1c040000, 0x1c040000, 0x1c040000 } }, - { 6, 0x989c, { 0x000a0000, 0x000a0000, 0x000a0000 } }, - { 6, 0x989c, { 0x00a10000, 0x00a10000, 0x00a10000 } }, - { 6, 0x989c, { 0x00400000, 0x00400000, 0x00400000 } }, - { 6, 0x989c, { 0x03090000, 0x03090000, 0x03090000 } }, - { 6, 0x989c, { 0x06000000, 0x06000000, 0x06000000 } }, - { 6, 0x989c, { 0x000000b0, 0x000000a8, 0x000000a8 } }, - { 6, 0x989c, { 0x0000002e, 0x0000002e, 0x0000002e } }, - { 6, 0x989c, { 0x006c4a41, 0x006c4af1, 0x006c4a61 } }, - { 6, 0x989c, { 0x0050892a, 0x0050892b, 0x0050892b } }, - { 6, 0x989c, { 0x00842400, 0x00842400, 0x00842400 } }, - { 6, 0x989c, { 0x00c69200, 0x00c69200, 0x00c69200 } }, - { 6, 0x98d0, { 0x0002000c, 0x0002000c, 0x0002000c } }, - { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } }, - { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } }, - { 7, 0x989c, { 0x0000000a, 0x00000012, 0x00000012 } }, - { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } }, - { 7, 0x989c, { 0x000000c1, 0x000000c1, 0x000000c1 } }, - { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } }, - { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } }, - { 7, 0x989c, { 0x00000022, 0x00000022, 0x00000022 } }, - { 7, 0x989c, { 0x00000092, 0x00000092, 0x00000092 } }, - { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } }, - { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } }, - { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } }, - { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } }, -}; - -/* RFX112A (Derby 2) */ - -/* BANK 6 len pos col */ -#define AR5K_RF5112A_OB_2GHZ { 3, 287, 0 } -#define AR5K_RF5112A_DB_2GHZ { 3, 290, 0 } - -#define AR5K_RF5112A_OB_5GHZ { 3, 279, 0 } -#define AR5K_RF5112A_DB_5GHZ { 3, 282, 0 } - -#define AR5K_RF5112A_FIXED_BIAS_A { 1, 278, 0 } -#define AR5K_RF5112A_FIXED_BIAS_B { 1, 277, 0 } - -#define AR5K_RF5112A_XPD_SEL { 1, 302, 0 } -#define AR5K_RF5112A_PDGAINLO { 2, 270, 0 } -#define AR5K_RF5112A_PDGAINHI { 2, 257, 0 } - -/* Access to PWD registers */ -#define AR5K_RF5112A_PWD(_n) { 1, (306 - _n), 3 } - -/* Voltage regulators */ -#define AR5K_RF5112A_HIGH_VC_CP { 2, 90, 2 } -#define AR5K_RF5112A_MID_VC_CP { 2, 92, 2 } -#define AR5K_RF5112A_LOW_VC_CP { 2, 94, 2 } -#define AR5K_RF5112A_PUSH_UP { 1, 254, 2 } - -/* Power consumption */ -#define AR5K_RF5112A_PAD2GND { 1, 281, 1 } -#define AR5K_RF5112A_XB2_LVL { 2, 1, 3 } -#define AR5K_RF5112A_XB5_LVL { 2, 3, 3 } - -static const struct ath5k_rf_reg rf_regs_5112a[] = { - {2, AR5K_RF_TURBO, AR5K_RF5112X_RF_TURBO}, - {6, AR5K_RF_OB_2GHZ, AR5K_RF5112A_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF5112A_DB_2GHZ}, - {6, AR5K_RF_OB_5GHZ, AR5K_RF5112A_OB_5GHZ}, - {6, AR5K_RF_DB_5GHZ, AR5K_RF5112A_DB_5GHZ}, - {6, AR5K_RF_FIXED_BIAS_A, AR5K_RF5112A_FIXED_BIAS_A}, - {6, AR5K_RF_FIXED_BIAS_B, AR5K_RF5112A_FIXED_BIAS_B}, - {6, AR5K_RF_XPD_SEL, AR5K_RF5112A_XPD_SEL}, - {6, AR5K_RF_PD_GAIN_LO, AR5K_RF5112A_PDGAINLO}, - {6, AR5K_RF_PD_GAIN_HI, AR5K_RF5112A_PDGAINHI}, - {6, AR5K_RF_PWD_130, AR5K_RF5112A_PWD(130)}, - {6, AR5K_RF_PWD_131, AR5K_RF5112A_PWD(131)}, - {6, AR5K_RF_PWD_132, AR5K_RF5112A_PWD(132)}, - {6, AR5K_RF_PWD_136, AR5K_RF5112A_PWD(136)}, - {6, AR5K_RF_PWD_137, AR5K_RF5112A_PWD(137)}, - {6, AR5K_RF_PWD_138, AR5K_RF5112A_PWD(138)}, - {6, AR5K_RF_PWD_166, AR5K_RF5112A_PWD(166)}, - {6, AR5K_RF_PWD_167, AR5K_RF5112A_PWD(167)}, - {6, AR5K_RF_HIGH_VC_CP, AR5K_RF5112A_HIGH_VC_CP}, - {6, AR5K_RF_MID_VC_CP, AR5K_RF5112A_MID_VC_CP}, - {6, AR5K_RF_LOW_VC_CP, AR5K_RF5112A_LOW_VC_CP}, - {6, AR5K_RF_PUSH_UP, AR5K_RF5112A_PUSH_UP}, - {6, AR5K_RF_PAD2GND, AR5K_RF5112A_PAD2GND}, - {6, AR5K_RF_XB2_LVL, AR5K_RF5112A_XB2_LVL}, - {6, AR5K_RF_XB5_LVL, AR5K_RF5112A_XB5_LVL}, - {7, AR5K_RF_GAIN_I, AR5K_RF5112X_GAIN_I}, - {7, AR5K_RF_MIXVGA_OVR, AR5K_RF5112X_MIXVGA_OVR}, - {7, AR5K_RF_MIXGAIN_OVR, AR5K_RF5112X_MIXGAIN_OVR}, - {7, AR5K_RF_MIXGAIN_STEP, AR5K_RF5112X_MIXGAIN_STEP}, - {7, AR5K_RF_PD_DELAY_A, AR5K_RF5112X_PD_DELAY_A}, - {7, AR5K_RF_PD_DELAY_B, AR5K_RF5112X_PD_DELAY_B}, - {7, AR5K_RF_PD_DELAY_XR, AR5K_RF5112X_PD_DELAY_XR}, - {7, AR5K_RF_PD_PERIOD_A, AR5K_RF5112X_PD_PERIOD_A}, - {7, AR5K_RF_PD_PERIOD_B, AR5K_RF5112X_PD_PERIOD_B}, - {7, AR5K_RF_PD_PERIOD_XR, AR5K_RF5112X_PD_PERIOD_XR}, -}; - -/* Default mode specific settings */ -static const struct ath5k_ini_rfbuffer rfb_5112a[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x03060408, 0x03060408, 0x03060408 } }, - { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00800000, 0x00800000, 0x00800000 } }, - { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, { 0x00010000, 0x00010000, 0x00010000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00180000, 0x00180000, 0x00180000 } }, - { 6, 0x989c, { 0x00600000, 0x006e0000, 0x006e0000 } }, - { 6, 0x989c, { 0x00c70000, 0x00c70000, 0x00c70000 } }, - { 6, 0x989c, { 0x004b0000, 0x004b0000, 0x004b0000 } }, - { 6, 0x989c, { 0x04480000, 0x04480000, 0x04480000 } }, - { 6, 0x989c, { 0x004c0000, 0x004c0000, 0x004c0000 } }, - { 6, 0x989c, { 0x00e40000, 0x00e40000, 0x00e40000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00fc0000, 0x00fc0000, 0x00fc0000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x043f0000, 0x043f0000, 0x043f0000 } }, - { 6, 0x989c, { 0x000c0000, 0x000c0000, 0x000c0000 } }, - { 6, 0x989c, { 0x02190000, 0x02190000, 0x02190000 } }, - { 6, 0x989c, { 0x00240000, 0x00240000, 0x00240000 } }, - { 6, 0x989c, { 0x00b40000, 0x00b40000, 0x00b40000 } }, - { 6, 0x989c, { 0x00990000, 0x00990000, 0x00990000 } }, - { 6, 0x989c, { 0x00500000, 0x00500000, 0x00500000 } }, - { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, { 0x00120000, 0x00120000, 0x00120000 } }, - { 6, 0x989c, { 0xc0320000, 0xc0320000, 0xc0320000 } }, - { 6, 0x989c, { 0x01740000, 0x01740000, 0x01740000 } }, - { 6, 0x989c, { 0x00110000, 0x00110000, 0x00110000 } }, - { 6, 0x989c, { 0x86280000, 0x86280000, 0x86280000 } }, - { 6, 0x989c, { 0x31840000, 0x31840000, 0x31840000 } }, - { 6, 0x989c, { 0x00f20080, 0x00f20080, 0x00f20080 } }, - { 6, 0x989c, { 0x00270019, 0x00270019, 0x00270019 } }, - { 6, 0x989c, { 0x00000003, 0x00000003, 0x00000003 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x000000b2, 0x000000b2, 0x000000b2 } }, - { 6, 0x989c, { 0x00b02084, 0x00b02084, 0x00b02084 } }, - { 6, 0x989c, { 0x004125a4, 0x004125a4, 0x004125a4 } }, - { 6, 0x989c, { 0x00119220, 0x00119220, 0x00119220 } }, - { 6, 0x989c, { 0x001a4800, 0x001a4800, 0x001a4800 } }, - { 6, 0x98d8, { 0x000b0230, 0x000b0230, 0x000b0230 } }, - { 7, 0x989c, { 0x00000094, 0x00000094, 0x00000094 } }, - { 7, 0x989c, { 0x00000091, 0x00000091, 0x00000091 } }, - { 7, 0x989c, { 0x00000012, 0x00000012, 0x00000012 } }, - { 7, 0x989c, { 0x00000080, 0x00000080, 0x00000080 } }, - { 7, 0x989c, { 0x000000d9, 0x000000d9, 0x000000d9 } }, - { 7, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } }, - { 7, 0x989c, { 0x000000f0, 0x000000f0, 0x000000f0 } }, - { 7, 0x989c, { 0x000000a2, 0x000000a2, 0x000000a2 } }, - { 7, 0x989c, { 0x00000052, 0x00000052, 0x00000052 } }, - { 7, 0x989c, { 0x000000d4, 0x000000d4, 0x000000d4 } }, - { 7, 0x989c, { 0x000014cc, 0x000014cc, 0x000014cc } }, - { 7, 0x989c, { 0x0000048c, 0x0000048c, 0x0000048c } }, - { 7, 0x98c4, { 0x00000003, 0x00000003, 0x00000003 } }, -}; - - - -/******************\ -* RF2413 (Griffin) * -\******************/ - -/* BANK 2 len pos col */ -#define AR5K_RF2413_RF_TURBO { 1, 1, 2 } - -/* BANK 6 len pos col */ -#define AR5K_RF2413_OB_2GHZ { 3, 168, 0 } -#define AR5K_RF2413_DB_2GHZ { 3, 165, 0 } - -static const struct ath5k_rf_reg rf_regs_2413[] = { - {2, AR5K_RF_TURBO, AR5K_RF2413_RF_TURBO}, - {6, AR5K_RF_OB_2GHZ, AR5K_RF2413_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF2413_DB_2GHZ}, -}; - -/* Default mode specific settings - * XXX: a/aTurbo ??? - */ -static const struct ath5k_ini_rfbuffer rfb_2413[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, { 0xf0000000, 0xf0000000, 0xf0000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x03000000, 0x03000000, 0x03000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x40400000, 0x40400000, 0x40400000 } }, - { 6, 0x989c, { 0x65050000, 0x65050000, 0x65050000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00420000, 0x00420000, 0x00420000 } }, - { 6, 0x989c, { 0x00b50000, 0x00b50000, 0x00b50000 } }, - { 6, 0x989c, { 0x00030000, 0x00030000, 0x00030000 } }, - { 6, 0x989c, { 0x00f70000, 0x00f70000, 0x00f70000 } }, - { 6, 0x989c, { 0x009d0000, 0x009d0000, 0x009d0000 } }, - { 6, 0x989c, { 0x00220000, 0x00220000, 0x00220000 } }, - { 6, 0x989c, { 0x04220000, 0x04220000, 0x04220000 } }, - { 6, 0x989c, { 0x00230018, 0x00230018, 0x00230018 } }, - { 6, 0x989c, { 0x00280000, 0x00280060, 0x00280060 } }, - { 6, 0x989c, { 0x005000c0, 0x005000c3, 0x005000c3 } }, - { 6, 0x989c, { 0x0004007f, 0x0004007f, 0x0004007f } }, - { 6, 0x989c, { 0x00000458, 0x00000458, 0x00000458 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x0000c000, 0x0000c000, 0x0000c000 } }, - { 6, 0x98d8, { 0x00400230, 0x00400230, 0x00400230 } }, - { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, -}; - - - -/***************************\ -* RF2315/RF2316 (Cobra SoC) * -\***************************/ - -/* BANK 2 len pos col */ -#define AR5K_RF2316_RF_TURBO { 1, 1, 2 } - -/* BANK 6 len pos col */ -#define AR5K_RF2316_OB_2GHZ { 3, 178, 0 } -#define AR5K_RF2316_DB_2GHZ { 3, 175, 0 } - -static const struct ath5k_rf_reg rf_regs_2316[] = { - {2, AR5K_RF_TURBO, AR5K_RF2316_RF_TURBO}, - {6, AR5K_RF_OB_2GHZ, AR5K_RF2316_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF2316_DB_2GHZ}, -}; - -/* Default mode specific settings */ -static const struct ath5k_ini_rfbuffer rfb_2316[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0xc0000000, 0xc0000000, 0xc0000000 } }, - { 6, 0x989c, { 0x0f000000, 0x0f000000, 0x0f000000 } }, - { 6, 0x989c, { 0x02000000, 0x02000000, 0x02000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0xf8000000, 0xf8000000, 0xf8000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x95150000, 0x95150000, 0x95150000 } }, - { 6, 0x989c, { 0xc1000000, 0xc1000000, 0xc1000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00080000, 0x00080000, 0x00080000 } }, - { 6, 0x989c, { 0x00d50000, 0x00d50000, 0x00d50000 } }, - { 6, 0x989c, { 0x000e0000, 0x000e0000, 0x000e0000 } }, - { 6, 0x989c, { 0x00dc0000, 0x00dc0000, 0x00dc0000 } }, - { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } }, - { 6, 0x989c, { 0x008a0000, 0x008a0000, 0x008a0000 } }, - { 6, 0x989c, { 0x10880000, 0x10880000, 0x10880000 } }, - { 6, 0x989c, { 0x008c0060, 0x008c0060, 0x008c0060 } }, - { 6, 0x989c, { 0x00a00000, 0x00a00080, 0x00a00080 } }, - { 6, 0x989c, { 0x00400000, 0x0040000d, 0x0040000d } }, - { 6, 0x989c, { 0x00110400, 0x00110400, 0x00110400 } }, - { 6, 0x989c, { 0x00000060, 0x00000060, 0x00000060 } }, - { 6, 0x989c, { 0x00000001, 0x00000001, 0x00000001 } }, - { 6, 0x989c, { 0x00000b00, 0x00000b00, 0x00000b00 } }, - { 6, 0x989c, { 0x00000be8, 0x00000be8, 0x00000be8 } }, - { 6, 0x98c0, { 0x00010000, 0x00010000, 0x00010000 } }, - { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, -}; - - - -/******************************\ -* RF5413/RF5424 (Eagle/Condor) * -\******************************/ - -/* BANK 6 len pos col */ -#define AR5K_RF5413_OB_2GHZ { 3, 241, 0 } -#define AR5K_RF5413_DB_2GHZ { 3, 238, 0 } - -#define AR5K_RF5413_OB_5GHZ { 3, 247, 0 } -#define AR5K_RF5413_DB_5GHZ { 3, 244, 0 } - -#define AR5K_RF5413_PWD_ICLOBUF2G { 3, 131, 3 } -#define AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 } - -static const struct ath5k_rf_reg rf_regs_5413[] = { - {6, AR5K_RF_OB_2GHZ, AR5K_RF5413_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF5413_DB_2GHZ}, - {6, AR5K_RF_OB_5GHZ, AR5K_RF5413_OB_5GHZ}, - {6, AR5K_RF_DB_5GHZ, AR5K_RF5413_DB_5GHZ}, - {6, AR5K_RF_PWD_ICLOBUF_2G, AR5K_RF5413_PWD_ICLOBUF2G}, - {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE}, -}; - -/* Default mode specific settings */ -static const struct ath5k_ini_rfbuffer rfb_5413[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x00000008, 0x00000008, 0x00000008 } }, - { 3, 0x98dc, { 0x00a000c0, 0x00e000c0, 0x00e000c0 } }, - { 6, 0x989c, { 0x33000000, 0x33000000, 0x33000000 } }, - { 6, 0x989c, { 0x01000000, 0x01000000, 0x01000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x1f000000, 0x1f000000, 0x1f000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00b80000, 0x00b80000, 0x00b80000 } }, - { 6, 0x989c, { 0x00b70000, 0x00b70000, 0x00b70000 } }, - { 6, 0x989c, { 0x00840000, 0x00840000, 0x00840000 } }, - { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } }, - { 6, 0x989c, { 0x00c00000, 0x00c00000, 0x00c00000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x00ff0000, 0x00ff0000, 0x00ff0000 } }, - { 6, 0x989c, { 0x00d70000, 0x00d70000, 0x00d70000 } }, - { 6, 0x989c, { 0x00610000, 0x00610000, 0x00610000 } }, - { 6, 0x989c, { 0x00fe0000, 0x00fe0000, 0x00fe0000 } }, - { 6, 0x989c, { 0x00de0000, 0x00de0000, 0x00de0000 } }, - { 6, 0x989c, { 0x007f0000, 0x007f0000, 0x007f0000 } }, - { 6, 0x989c, { 0x043d0000, 0x043d0000, 0x043d0000 } }, - { 6, 0x989c, { 0x00770000, 0x00770000, 0x00770000 } }, - { 6, 0x989c, { 0x00440000, 0x00440000, 0x00440000 } }, - { 6, 0x989c, { 0x00980000, 0x00980000, 0x00980000 } }, - { 6, 0x989c, { 0x00100080, 0x00100080, 0x00100080 } }, - { 6, 0x989c, { 0x0005c034, 0x0005c034, 0x0005c034 } }, - { 6, 0x989c, { 0x003100f0, 0x003100f0, 0x003100f0 } }, - { 6, 0x989c, { 0x000c011f, 0x000c011f, 0x000c011f } }, - { 6, 0x989c, { 0x00510040, 0x00510040, 0x00510040 } }, - { 6, 0x989c, { 0x005000da, 0x005000da, 0x005000da } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00004044, 0x00004044, 0x00004044 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x000060c0, 0x000060c0, 0x000060c0 } }, - { 6, 0x989c, { 0x00002c00, 0x00003600, 0x00003600 } }, - { 6, 0x98c8, { 0x00000403, 0x00040403, 0x00040403 } }, - { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, -}; - - - -/***************************\ -* RF2425/RF2417 (Swan/Nala) * -* AR2317 (Spider SoC) * -\***************************/ - -/* BANK 2 len pos col */ -#define AR5K_RF2425_RF_TURBO { 1, 1, 2 } - -/* BANK 6 len pos col */ -#define AR5K_RF2425_OB_2GHZ { 3, 193, 0 } -#define AR5K_RF2425_DB_2GHZ { 3, 190, 0 } - -static const struct ath5k_rf_reg rf_regs_2425[] = { - {2, AR5K_RF_TURBO, AR5K_RF2425_RF_TURBO}, - {6, AR5K_RF_OB_2GHZ, AR5K_RF2425_OB_2GHZ}, - {6, AR5K_RF_DB_2GHZ, AR5K_RF2425_DB_2GHZ}, -}; - -/* Default mode specific settings - */ -static const struct ath5k_ini_rfbuffer rfb_2425[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } }, - { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } }, - { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } }, - { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } }, - { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } }, - { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } }, - { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } }, - { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } }, - { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } }, - { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } }, - { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } }, - { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } }, - { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, -}; - -/* - * TODO: Handle the few differences with swan during - * bank modification and get rid of this - */ -static const struct ath5k_ini_rfbuffer rfb_2317[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } }, - { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } }, - { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } }, - { 6, 0x989c, { 0x00e70000, 0x00e70000, 0x00e70000 } }, - { 6, 0x989c, { 0x00140100, 0x00140100, 0x00140100 } }, - { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } }, - { 6, 0x989c, { 0x0007001a, 0x0007001a, 0x0007001a } }, - { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } }, - { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } }, - { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } }, - { 6, 0x989c, { 0x00009688, 0x00009688, 0x00009688 } }, - { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } }, - { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, -}; - -/* - * TODO: Handle the few differences with swan during - * bank modification and get rid of this - */ -static const struct ath5k_ini_rfbuffer rfb_2417[] = { - /* BANK / C.R. A/XR B G */ - { 1, 0x98d4, { 0x00000020, 0x00000020, 0x00000020 } }, - { 2, 0x98d0, { 0x02001408, 0x02001408, 0x02001408 } }, - { 3, 0x98dc, { 0x00a020c0, 0x00e020c0, 0x00e020c0 } }, - { 6, 0x989c, { 0x10000000, 0x10000000, 0x10000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x002a0000, 0x002a0000, 0x002a0000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00100000, 0x00100000, 0x00100000 } }, - { 6, 0x989c, { 0x00020000, 0x00020000, 0x00020000 } }, - { 6, 0x989c, { 0x00730000, 0x00730000, 0x00730000 } }, - { 6, 0x989c, { 0x00f80000, 0x00f80000, 0x00f80000 } }, - { 6, 0x989c, { 0x00e70000, 0x80e70000, 0x80e70000 } }, - { 6, 0x989c, { 0x00140000, 0x00140000, 0x00140000 } }, - { 6, 0x989c, { 0x00910040, 0x00910040, 0x00910040 } }, - { 6, 0x989c, { 0x0007001a, 0x0207001a, 0x0207001a } }, - { 6, 0x989c, { 0x00410000, 0x00410000, 0x00410000 } }, - { 6, 0x989c, { 0x00810000, 0x00810060, 0x00810060 } }, - { 6, 0x989c, { 0x00020800, 0x00020803, 0x00020803 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00000000, 0x00000000, 0x00000000 } }, - { 6, 0x989c, { 0x00001660, 0x00001660, 0x00001660 } }, - { 6, 0x989c, { 0x00001688, 0x00001688, 0x00001688 } }, - { 6, 0x98c4, { 0x00000001, 0x00000001, 0x00000001 } }, - { 7, 0x989c, { 0x00006400, 0x00006400, 0x00006400 } }, - { 7, 0x989c, { 0x00000800, 0x00000800, 0x00000800 } }, - { 7, 0x98cc, { 0x0000000e, 0x0000000e, 0x0000000e } }, -}; diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfgain.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfgain.h deleted file mode 100644 index 4d21df0e..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfgain.h +++ /dev/null @@ -1,534 +0,0 @@ -/* - * RF Gain optimization - * - * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com> - * - * Permission to use, copy, modify, and 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. - * - */ - -/** - * struct ath5k_ini_rfgain - RF Gain table - * @rfg_register: RF Gain register address - * @rfg_value: Register value for 5 and 2GHz - * - * Mode-specific RF Gain table (64bytes) for RF5111/5112 - * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial - * RF Gain values are included in AR5K_AR5210_INI) - */ -struct ath5k_ini_rfgain { - u16 rfg_register; - u32 rfg_value[2]; /* [freq (see below)] */ -}; - -/* Initial RF Gain settings for RF5111 */ -static const struct ath5k_ini_rfgain rfgain_5111[] = { - /* 5GHz 2GHz */ - { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } }, - { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } }, - { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } }, - { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } }, - { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } }, - { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } }, - { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } }, - { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } }, - { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } }, - { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } }, - { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } }, - { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } }, - { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } }, - { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } }, - { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } }, - { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } }, - { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } }, - { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } }, - { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } }, - { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } }, - { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } }, - { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } }, - { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } }, - { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } }, - { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } }, - { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } }, - { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } }, - { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } }, - { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } }, - { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } }, - { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } }, - { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } }, - { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } }, - { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } }, - { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } }, - { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } }, - { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } }, - { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } }, - { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } }, - { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } }, - { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } }, - { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } }, - { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } }, - { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } }, - { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } }, - { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } }, - { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } }, - { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } }, - { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } }, - { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } }, - { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } }, - { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } }, -}; - -/* Initial RF Gain settings for RF5112 */ -static const struct ath5k_ini_rfgain rfgain_5112[] = { - /* 5GHz 2GHz */ - { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } }, - { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } }, - { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } }, - { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } }, - { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } }, - { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } }, - { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } }, - { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } }, - { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } }, - { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } }, - { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } }, - { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } }, - { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } }, - { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } }, - { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } }, - { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } }, - { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } }, - { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } }, - { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } }, - { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } }, - { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } }, - { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } }, - { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } }, - { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } }, - { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } }, - { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } }, - { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } }, - { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } }, - { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } }, - { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } }, - { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } }, - { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } }, - { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } }, - { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } }, - { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } }, - { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } }, - { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } }, - { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } }, - { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } }, - { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } }, - { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } }, - { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } }, - { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } }, - { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } }, - { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } }, - { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } }, - { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } }, - { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } }, - { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } }, - { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } }, - { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } }, - { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } }, - { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } }, - { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } }, - { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } }, - { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } }, -}; - -/* Initial RF Gain settings for RF2413 */ -static const struct ath5k_ini_rfgain rfgain_2413[] = { - { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, - { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } }, - { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } }, - { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } }, - { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } }, - { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } }, - { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } }, - { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } }, - { AR5K_RF_GAIN(8), { 0x00000000, 0x00000168 } }, - { AR5K_RF_GAIN(9), { 0x00000000, 0x000001a8 } }, - { AR5K_RF_GAIN(10), { 0x00000000, 0x000001e8 } }, - { AR5K_RF_GAIN(11), { 0x00000000, 0x00000028 } }, - { AR5K_RF_GAIN(12), { 0x00000000, 0x00000068 } }, - { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } }, - { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } }, - { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } }, - { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } }, - { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } }, - { AR5K_RF_GAIN(18), { 0x00000000, 0x00000190 } }, - { AR5K_RF_GAIN(19), { 0x00000000, 0x000001d0 } }, - { AR5K_RF_GAIN(20), { 0x00000000, 0x00000010 } }, - { AR5K_RF_GAIN(21), { 0x00000000, 0x00000050 } }, - { AR5K_RF_GAIN(22), { 0x00000000, 0x00000090 } }, - { AR5K_RF_GAIN(23), { 0x00000000, 0x00000191 } }, - { AR5K_RF_GAIN(24), { 0x00000000, 0x000001d1 } }, - { AR5K_RF_GAIN(25), { 0x00000000, 0x00000011 } }, - { AR5K_RF_GAIN(26), { 0x00000000, 0x00000051 } }, - { AR5K_RF_GAIN(27), { 0x00000000, 0x00000091 } }, - { AR5K_RF_GAIN(28), { 0x00000000, 0x00000178 } }, - { AR5K_RF_GAIN(29), { 0x00000000, 0x000001b8 } }, - { AR5K_RF_GAIN(30), { 0x00000000, 0x000001f8 } }, - { AR5K_RF_GAIN(31), { 0x00000000, 0x00000038 } }, - { AR5K_RF_GAIN(32), { 0x00000000, 0x00000078 } }, - { AR5K_RF_GAIN(33), { 0x00000000, 0x00000199 } }, - { AR5K_RF_GAIN(34), { 0x00000000, 0x000001d9 } }, - { AR5K_RF_GAIN(35), { 0x00000000, 0x00000019 } }, - { AR5K_RF_GAIN(36), { 0x00000000, 0x00000059 } }, - { AR5K_RF_GAIN(37), { 0x00000000, 0x00000099 } }, - { AR5K_RF_GAIN(38), { 0x00000000, 0x000000d9 } }, - { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } }, -}; - -/* Initial RF Gain settings for AR2316 */ -static const struct ath5k_ini_rfgain rfgain_2316[] = { - { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, - { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } }, - { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } }, - { AR5K_RF_GAIN(3), { 0x00000000, 0x000000c0 } }, - { AR5K_RF_GAIN(4), { 0x00000000, 0x000000e0 } }, - { AR5K_RF_GAIN(5), { 0x00000000, 0x000000e0 } }, - { AR5K_RF_GAIN(6), { 0x00000000, 0x00000128 } }, - { AR5K_RF_GAIN(7), { 0x00000000, 0x00000128 } }, - { AR5K_RF_GAIN(8), { 0x00000000, 0x00000128 } }, - { AR5K_RF_GAIN(9), { 0x00000000, 0x00000168 } }, - { AR5K_RF_GAIN(10), { 0x00000000, 0x000001a8 } }, - { AR5K_RF_GAIN(11), { 0x00000000, 0x000001e8 } }, - { AR5K_RF_GAIN(12), { 0x00000000, 0x00000028 } }, - { AR5K_RF_GAIN(13), { 0x00000000, 0x00000068 } }, - { AR5K_RF_GAIN(14), { 0x00000000, 0x000000a8 } }, - { AR5K_RF_GAIN(15), { 0x00000000, 0x000000e8 } }, - { AR5K_RF_GAIN(16), { 0x00000000, 0x000000e8 } }, - { AR5K_RF_GAIN(17), { 0x00000000, 0x00000130 } }, - { AR5K_RF_GAIN(18), { 0x00000000, 0x00000130 } }, - { AR5K_RF_GAIN(19), { 0x00000000, 0x00000170 } }, - { AR5K_RF_GAIN(20), { 0x00000000, 0x000001b0 } }, - { AR5K_RF_GAIN(21), { 0x00000000, 0x000001f0 } }, - { AR5K_RF_GAIN(22), { 0x00000000, 0x00000030 } }, - { AR5K_RF_GAIN(23), { 0x00000000, 0x00000070 } }, - { AR5K_RF_GAIN(24), { 0x00000000, 0x000000b0 } }, - { AR5K_RF_GAIN(25), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(26), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(27), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(28), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(29), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(30), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(31), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(32), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(33), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(34), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(35), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(36), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f0 } }, - { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f0 } }, -}; - - -/* Initial RF Gain settings for RF5413 */ -static const struct ath5k_ini_rfgain rfgain_5413[] = { - /* 5GHz 2GHz */ - { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, - { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } }, - { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } }, - { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } }, - { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } }, - { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } }, - { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } }, - { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } }, - { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } }, - { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } }, - { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } }, - { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } }, - { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } }, - { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } }, - { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } }, - { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } }, - { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } }, - { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } }, - { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } }, - { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } }, - { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } }, - { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } }, - { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } }, - { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } }, - { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } }, - { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } }, - { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } }, - { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } }, - { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } }, - { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } }, - { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } }, - { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } }, - { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } }, - { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } }, - { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } }, - { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } }, - { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } }, - { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } }, - { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } }, - { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } }, - { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } }, -}; - - -/* Initial RF Gain settings for RF2425 */ -static const struct ath5k_ini_rfgain rfgain_2425[] = { - { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } }, - { AR5K_RF_GAIN(1), { 0x00000000, 0x00000040 } }, - { AR5K_RF_GAIN(2), { 0x00000000, 0x00000080 } }, - { AR5K_RF_GAIN(3), { 0x00000000, 0x00000181 } }, - { AR5K_RF_GAIN(4), { 0x00000000, 0x000001c1 } }, - { AR5K_RF_GAIN(5), { 0x00000000, 0x00000001 } }, - { AR5K_RF_GAIN(6), { 0x00000000, 0x00000041 } }, - { AR5K_RF_GAIN(7), { 0x00000000, 0x00000081 } }, - { AR5K_RF_GAIN(8), { 0x00000000, 0x00000188 } }, - { AR5K_RF_GAIN(9), { 0x00000000, 0x000001c8 } }, - { AR5K_RF_GAIN(10), { 0x00000000, 0x00000008 } }, - { AR5K_RF_GAIN(11), { 0x00000000, 0x00000048 } }, - { AR5K_RF_GAIN(12), { 0x00000000, 0x00000088 } }, - { AR5K_RF_GAIN(13), { 0x00000000, 0x00000189 } }, - { AR5K_RF_GAIN(14), { 0x00000000, 0x000001c9 } }, - { AR5K_RF_GAIN(15), { 0x00000000, 0x00000009 } }, - { AR5K_RF_GAIN(16), { 0x00000000, 0x00000049 } }, - { AR5K_RF_GAIN(17), { 0x00000000, 0x00000089 } }, - { AR5K_RF_GAIN(18), { 0x00000000, 0x000001b0 } }, - { AR5K_RF_GAIN(19), { 0x00000000, 0x000001f0 } }, - { AR5K_RF_GAIN(20), { 0x00000000, 0x00000030 } }, - { AR5K_RF_GAIN(21), { 0x00000000, 0x00000070 } }, - { AR5K_RF_GAIN(22), { 0x00000000, 0x00000171 } }, - { AR5K_RF_GAIN(23), { 0x00000000, 0x000001b1 } }, - { AR5K_RF_GAIN(24), { 0x00000000, 0x000001f1 } }, - { AR5K_RF_GAIN(25), { 0x00000000, 0x00000031 } }, - { AR5K_RF_GAIN(26), { 0x00000000, 0x00000071 } }, - { AR5K_RF_GAIN(27), { 0x00000000, 0x000001b8 } }, - { AR5K_RF_GAIN(28), { 0x00000000, 0x000001f8 } }, - { AR5K_RF_GAIN(29), { 0x00000000, 0x00000038 } }, - { AR5K_RF_GAIN(30), { 0x00000000, 0x00000078 } }, - { AR5K_RF_GAIN(31), { 0x00000000, 0x000000b8 } }, - { AR5K_RF_GAIN(32), { 0x00000000, 0x000001b9 } }, - { AR5K_RF_GAIN(33), { 0x00000000, 0x000001f9 } }, - { AR5K_RF_GAIN(34), { 0x00000000, 0x00000039 } }, - { AR5K_RF_GAIN(35), { 0x00000000, 0x00000079 } }, - { AR5K_RF_GAIN(36), { 0x00000000, 0x000000b9 } }, - { AR5K_RF_GAIN(37), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(38), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(39), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(40), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(41), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(42), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(43), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(44), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(45), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(46), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(47), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(48), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(49), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(50), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(51), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(52), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(53), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(54), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(55), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(56), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(57), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(58), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(59), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(60), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(61), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(62), { 0x00000000, 0x000000f9 } }, - { AR5K_RF_GAIN(63), { 0x00000000, 0x000000f9 } }, -}; - -#define AR5K_GAIN_CRN_FIX_BITS_5111 4 -#define AR5K_GAIN_CRN_FIX_BITS_5112 7 -#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112 -#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15 -#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20 -#define AR5K_GAIN_CCK_PROBE_CORR 5 -#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15 -#define AR5K_GAIN_STEP_COUNT 10 - -/* Check if our current measurement is inside our - * current variable attenuation window */ -#define AR5K_GAIN_CHECK_ADJUST(_g) \ - ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high) - -/** - * struct ath5k_gain_opt_step - An RF gain optimization step - * @gos_param: Set of parameters - * @gos_gain: Gain - */ -struct ath5k_gain_opt_step { - s8 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS]; - s8 gos_gain; -}; - -/** - * struct ath5k_gain_opt - RF Gain optimization ladder - * @go_default: The default step - * @go_steps_count: How many optimization steps - * @go_step: Array of &struct ath5k_gain_opt_step - */ -struct ath5k_gain_opt { - u8 go_default; - u8 go_steps_count; - const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT]; -}; - - -/* - * RF5111 - * Parameters on gos_param: - * 1) Tx clip PHY register - * 2) PWD 90 RF register - * 3) PWD 84 RF register - * 4) RFGainSel RF register - */ -static const struct ath5k_gain_opt rfgain_opt_5111 = { - 4, - 9, - { - { { 4, 1, 1, 1 }, 6 }, - { { 4, 0, 1, 1 }, 4 }, - { { 3, 1, 1, 1 }, 3 }, - { { 4, 0, 0, 1 }, 1 }, - { { 4, 1, 1, 0 }, 0 }, - { { 4, 0, 1, 0 }, -2 }, - { { 3, 1, 1, 0 }, -3 }, - { { 4, 0, 0, 0 }, -4 }, - { { 2, 1, 1, 0 }, -6 } - } -}; - -/* - * RF5112 - * Parameters on gos_param: - * 1) Mixgain ovr RF register - * 2) PWD 138 RF register - * 3) PWD 137 RF register - * 4) PWD 136 RF register - * 5) PWD 132 RF register - * 6) PWD 131 RF register - * 7) PWD 130 RF register - */ -static const struct ath5k_gain_opt rfgain_opt_5112 = { - 1, - 8, - { - { { 3, 0, 0, 0, 0, 0, 0 }, 6 }, - { { 2, 0, 0, 0, 0, 0, 0 }, 0 }, - { { 1, 0, 0, 0, 0, 0, 0 }, -3 }, - { { 0, 0, 0, 0, 0, 0, 0 }, -6 }, - { { 0, 1, 1, 0, 0, 0, 0 }, -8 }, - { { 0, 1, 1, 0, 1, 1, 0 }, -10 }, - { { 0, 1, 0, 1, 1, 1, 0 }, -13 }, - { { 0, 1, 0, 1, 1, 0, 1 }, -16 }, - } -}; - diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfkill.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfkill.c deleted file mode 100644 index 270a319f..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/rfkill.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * RFKILL support for ath5k - * - * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any - * redistribution must be conditioned upon including a substantially - * similar Disclaimer requirement for further binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * NO WARRANTY - * 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 NONINFRINGEMENT, MERCHANTIBILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. - */ - -#include "ath5k.h" - - -static inline void ath5k_rfkill_disable(struct ath5k_hw *ah) -{ - ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n", - ah->rf_kill.gpio, ah->rf_kill.polarity); - ath5k_hw_set_gpio_output(ah, ah->rf_kill.gpio); - ath5k_hw_set_gpio(ah, ah->rf_kill.gpio, !ah->rf_kill.polarity); -} - - -static inline void ath5k_rfkill_enable(struct ath5k_hw *ah) -{ - ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n", - ah->rf_kill.gpio, ah->rf_kill.polarity); - ath5k_hw_set_gpio_output(ah, ah->rf_kill.gpio); - ath5k_hw_set_gpio(ah, ah->rf_kill.gpio, ah->rf_kill.polarity); -} - -static inline void ath5k_rfkill_set_intr(struct ath5k_hw *ah, bool enable) -{ - u32 curval; - - ath5k_hw_set_gpio_input(ah, ah->rf_kill.gpio); - curval = ath5k_hw_get_gpio(ah, ah->rf_kill.gpio); - ath5k_hw_set_gpio_intr(ah, ah->rf_kill.gpio, enable ? - !!curval : !curval); -} - -static bool -ath5k_is_rfkill_set(struct ath5k_hw *ah) -{ - /* configuring GPIO for input for some reason disables rfkill */ - /*ath5k_hw_set_gpio_input(ah, ah->rf_kill.gpio);*/ - return ath5k_hw_get_gpio(ah, ah->rf_kill.gpio) == - ah->rf_kill.polarity; -} - -static void -ath5k_tasklet_rfkill_toggle(unsigned long data) -{ - struct ath5k_hw *ah = (void *)data; - bool blocked; - - blocked = ath5k_is_rfkill_set(ah); - wiphy_rfkill_set_hw_state(ah->hw->wiphy, blocked); -} - - -void -ath5k_rfkill_hw_start(struct ath5k_hw *ah) -{ - /* read rfkill GPIO configuration from EEPROM header */ - ah->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin; - ah->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol; - - tasklet_init(&ah->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle, - (unsigned long)ah); - - ath5k_rfkill_disable(ah); - - /* enable interrupt for rfkill switch */ - if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) - ath5k_rfkill_set_intr(ah, true); -} - - -void -ath5k_rfkill_hw_stop(struct ath5k_hw *ah) -{ - /* disable interrupt for rfkill switch */ - if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) - ath5k_rfkill_set_intr(ah, false); - - tasklet_kill(&ah->rf_kill.toggleq); - - /* enable RFKILL when stopping HW so Wifi LED is turned off */ - ath5k_rfkill_enable(ah); -} - diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/sysfs.c b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/sysfs.c deleted file mode 100644 index 9364da7b..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/sysfs.c +++ /dev/null @@ -1,120 +0,0 @@ -#include <linux/device.h> -#include <linux/pci.h> - -#include "ath5k.h" -#include "reg.h" - -#define SIMPLE_SHOW_STORE(name, get, set) \ -static ssize_t ath5k_attr_show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct ieee80211_hw *hw = dev_get_drvdata(dev); \ - struct ath5k_hw *ah = hw->priv; \ - return snprintf(buf, PAGE_SIZE, "%d\n", get); \ -} \ - \ -static ssize_t ath5k_attr_store_##name(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count) \ -{ \ - struct ieee80211_hw *hw = dev_get_drvdata(dev); \ - struct ath5k_hw *ah = hw->priv; \ - int val, ret; \ - \ - ret = kstrtoint(buf, 10, &val); \ - if (ret < 0) \ - return ret; \ - set(ah, val); \ - return count; \ -} \ -static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, \ - ath5k_attr_show_##name, ath5k_attr_store_##name) - -#define SIMPLE_SHOW(name, get) \ -static ssize_t ath5k_attr_show_##name(struct device *dev, \ - struct device_attribute *attr, \ - char *buf) \ -{ \ - struct ieee80211_hw *hw = dev_get_drvdata(dev); \ - struct ath5k_hw *ah = hw->priv; \ - return snprintf(buf, PAGE_SIZE, "%d\n", get); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) - -/*** ANI ***/ - -SIMPLE_SHOW_STORE(ani_mode, ah->ani_state.ani_mode, ath5k_ani_init); -SIMPLE_SHOW_STORE(noise_immunity_level, ah->ani_state.noise_imm_level, - ath5k_ani_set_noise_immunity_level); -SIMPLE_SHOW_STORE(spur_level, ah->ani_state.spur_level, - ath5k_ani_set_spur_immunity_level); -SIMPLE_SHOW_STORE(firstep_level, ah->ani_state.firstep_level, - ath5k_ani_set_firstep_level); -SIMPLE_SHOW_STORE(ofdm_weak_signal_detection, ah->ani_state.ofdm_weak_sig, - ath5k_ani_set_ofdm_weak_signal_detection); -SIMPLE_SHOW_STORE(cck_weak_signal_detection, ah->ani_state.cck_weak_sig, - ath5k_ani_set_cck_weak_signal_detection); -SIMPLE_SHOW(spur_level_max, ah->ani_state.max_spur_level); - -static ssize_t ath5k_attr_show_noise_immunity_level_max(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_NOISE_IMM_LVL); -} -static DEVICE_ATTR(noise_immunity_level_max, S_IRUGO, - ath5k_attr_show_noise_immunity_level_max, NULL); - -static ssize_t ath5k_attr_show_firstep_level_max(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", ATH5K_ANI_MAX_FIRSTEP_LVL); -} -static DEVICE_ATTR(firstep_level_max, S_IRUGO, - ath5k_attr_show_firstep_level_max, NULL); - -static struct attribute *ath5k_sysfs_entries_ani[] = { - &dev_attr_ani_mode.attr, - &dev_attr_noise_immunity_level.attr, - &dev_attr_spur_level.attr, - &dev_attr_firstep_level.attr, - &dev_attr_ofdm_weak_signal_detection.attr, - &dev_attr_cck_weak_signal_detection.attr, - &dev_attr_noise_immunity_level_max.attr, - &dev_attr_spur_level_max.attr, - &dev_attr_firstep_level_max.attr, - NULL -}; - -static struct attribute_group ath5k_attribute_group_ani = { - .name = "ani", - .attrs = ath5k_sysfs_entries_ani, -}; - - -/*** register / unregister ***/ - -int -ath5k_sysfs_register(struct ath5k_hw *ah) -{ - struct device *dev = ah->dev; - int err; - - err = sysfs_create_group(&dev->kobj, &ath5k_attribute_group_ani); - if (err) { - ATH5K_ERR(ah, "failed to create sysfs group\n"); - return err; - } - - return 0; -} - -void -ath5k_sysfs_unregister(struct ath5k_hw *ah) -{ - struct device *dev = ah->dev; - - sysfs_remove_group(&dev->kobj, &ath5k_attribute_group_ani); -} diff --git a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/trace.h b/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/trace.h deleted file mode 100644 index 00f01581..00000000 --- a/ANDROID_3.4.5/drivers/net/wireless/ath/ath5k/trace.h +++ /dev/null @@ -1,106 +0,0 @@ -#if !defined(__TRACE_ATH5K_H) || defined(TRACE_HEADER_MULTI_READ) -#define __TRACE_ATH5K_H - -#include <linux/tracepoint.h> - - -#if !defined(CONFIG_ATH5K_TRACER) || defined(__CHECKER__) -#undef TRACE_EVENT -#define TRACE_EVENT(name, proto, ...) \ -static inline void trace_ ## name(proto) {} -#endif - -struct sk_buff; -struct ath5k_txq; -struct ath5k_tx_status; - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM ath5k - -TRACE_EVENT(ath5k_rx, - TP_PROTO(struct ath5k_hw *priv, struct sk_buff *skb), - TP_ARGS(priv, skb), - TP_STRUCT__entry( - __field(struct ath5k_hw *, priv) - __field(unsigned long, skbaddr) - __dynamic_array(u8, frame, skb->len) - ), - TP_fast_assign( - __entry->priv = priv; - __entry->skbaddr = (unsigned long) skb; - memcpy(__get_dynamic_array(frame), skb->data, skb->len); - ), - TP_printk( - "[%p] RX skb=%lx", __entry->priv, __entry->skbaddr - ) -); - -TRACE_EVENT(ath5k_tx, - TP_PROTO(struct ath5k_hw *priv, struct sk_buff *skb, - struct ath5k_txq *q), - - TP_ARGS(priv, skb, q), - - TP_STRUCT__entry( - __field(struct ath5k_hw *, priv) - __field(unsigned long, skbaddr) - __field(u8, qnum) - __dynamic_array(u8, frame, skb->len) - ), - - TP_fast_assign( - __entry->priv = priv; - __entry->skbaddr = (unsigned long) skb; - __entry->qnum = (u8) q->qnum; - memcpy(__get_dynamic_array(frame), skb->data, skb->len); - ), - - TP_printk( - "[%p] TX skb=%lx q=%d", __entry->priv, __entry->skbaddr, - __entry->qnum - ) -); - -TRACE_EVENT(ath5k_tx_complete, - TP_PROTO(struct ath5k_hw *priv, struct sk_buff *skb, - struct ath5k_txq *q, struct ath5k_tx_status *ts), - - TP_ARGS(priv, skb, q, ts), - - TP_STRUCT__entry( - __field(struct ath5k_hw *, priv) - __field(unsigned long, skbaddr) - __field(u8, qnum) - __field(u8, ts_status) - __field(s8, ts_rssi) - __field(u8, ts_antenna) - ), - - TP_fast_assign( - __entry->priv = priv; - __entry->skbaddr = (unsigned long) skb; - __entry->qnum = (u8) q->qnum; - __entry->ts_status = ts->ts_status; - __entry->ts_rssi = ts->ts_rssi; - __entry->ts_antenna = ts->ts_antenna; - ), - - TP_printk( - "[%p] TX end skb=%lx q=%d stat=%x rssi=%d ant=%x", - __entry->priv, __entry->skbaddr, __entry->qnum, - __entry->ts_status, __entry->ts_rssi, __entry->ts_antenna - ) -); - -#endif /* __TRACE_ATH5K_H */ - -#if defined(CONFIG_ATH5K_TRACER) && !defined(__CHECKER__) - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k -#undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE trace - -#include <trace/define_trace.h> - -#endif |