···11config ATH5K22 tristate "Atheros 5xxx wireless cards support"33- depends on PCI && MAC8021133+ depends on (PCI || ATHEROS_AR231X) && MAC8021144 select MAC80211_LEDS55 select LEDS_CLASS66 select NEW_LEDS77 select AVERAGE88+ select ATH5K_AHB if (ATHEROS_AR231X && !PCI)99+ select ATH5K_PCI if (!ATHEROS_AR231X && PCI)810 ---help---911 This module adds support for wireless adapters based on1012 Atheros 5xxx chipset.···40384139 modprobe ath5k debug=0x0000040042404141+config ATH5K_AHB4242+ bool "Atheros 5xxx AHB bus support"4343+ depends on (ATHEROS_AR231X && !PCI)4444+ ---help---4545+ This adds support for WiSoC type chipsets of the 5xxx Atheros4646+ family.4747+4848+config ATH5K_PCI4949+ bool "Atheros 5xxx PCI bus support"5050+ depends on (!ATHEROS_AR231X && PCI)5151+ ---help---5252+ This adds support for PCI type chipsets of the 5xxx Atheros5353+ family.
···11+/*22+ * Copyright (c) 2008-2009 Atheros Communications Inc.33+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>44+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>55+ *66+ * Permission to use, copy, modify, and/or distribute this software for any77+ * purpose with or without fee is hereby granted, provided that the above88+ * copyright notice and this permission notice appear in all copies.99+ *1010+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES1111+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1212+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR1313+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1414+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1515+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1616+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1717+ */1818+1919+#include <linux/nl80211.h>2020+#include <linux/platform_device.h>2121+#include <ar231x_platform.h>2222+#include "ath5k.h"2323+#include "debug.h"2424+#include "base.h"2525+#include "reg.h"2626+#include "debug.h"2727+2828+/* return bus cachesize in 4B word units */2929+static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)3030+{3131+ *csz = L1_CACHE_BYTES >> 2;3232+}3333+3434+bool ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)3535+{3636+ struct ath5k_softc *sc = common->priv;3737+ struct platform_device *pdev = to_platform_device(sc->dev);3838+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;3939+ u16 *eeprom, *eeprom_end;4040+4141+4242+4343+ bcfg = pdev->dev.platform_data;4444+ eeprom = (u16 *) bcfg->radio;4545+ eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;4646+4747+ eeprom += off;4848+ if (eeprom > eeprom_end)4949+ return -EINVAL;5050+5151+ *data = *eeprom;5252+ return 0;5353+}5454+5555+int ath5k_hw_read_srev(struct ath5k_hw *ah)5656+{5757+ struct ath5k_softc *sc = ah->ah_sc;5858+ struct platform_device *pdev = to_platform_device(sc->dev);5959+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;6060+ ah->ah_mac_srev = bcfg->devid;6161+ return 0;6262+}6363+6464+static const struct ath_bus_ops ath_ahb_bus_ops = {6565+ .ath_bus_type = ATH_AHB,6666+ .read_cachesize = ath5k_ahb_read_cachesize,6767+ .eeprom_read = ath5k_ahb_eeprom_read,6868+};6969+7070+/*Initialization*/7171+static int ath_ahb_probe(struct platform_device *pdev)7272+{7373+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;7474+ struct ath5k_softc *sc;7575+ struct ieee80211_hw *hw;7676+ struct resource *res;7777+ void __iomem *mem;7878+ int irq;7979+ int ret = 0;8080+ u32 reg;8181+8282+ if (!pdev->dev.platform_data) {8383+ dev_err(&pdev->dev, "no platform data specified\n");8484+ ret = -EINVAL;8585+ goto err_out;8686+ }8787+8888+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);8989+ if (res == NULL) {9090+ dev_err(&pdev->dev, "no memory resource found\n");9191+ ret = -ENXIO;9292+ goto err_out;9393+ }9494+9595+ mem = ioremap_nocache(res->start, res->end - res->start + 1);9696+ if (mem == NULL) {9797+ dev_err(&pdev->dev, "ioremap failed\n");9898+ ret = -ENOMEM;9999+ goto err_out;100100+ }101101+102102+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);103103+ if (res == NULL) {104104+ dev_err(&pdev->dev, "no IRQ resource found\n");105105+ ret = -ENXIO;106106+ goto err_out;107107+ }108108+109109+ irq = res->start;110110+111111+ hw = ieee80211_alloc_hw(sizeof(struct ath5k_softc), &ath5k_hw_ops);112112+ if (hw == NULL) {113113+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");114114+ ret = -ENOMEM;115115+ goto err_out;116116+ }117117+118118+ sc = hw->priv;119119+ sc->hw = hw;120120+ sc->dev = &pdev->dev;121121+ sc->iobase = mem;122122+ sc->irq = irq;123123+ sc->devid = bcfg->devid;124124+125125+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {126126+ /* Enable WMAC AHB arbitration */127127+ reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);128128+ reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;129129+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);130130+131131+ /* Enable global WMAC swapping */132132+ reg = __raw_readl((void __iomem *) AR5K_AR2315_BYTESWAP);133133+ reg |= AR5K_AR2315_BYTESWAP_WMAC;134134+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);135135+ } else {136136+ /* Enable WMAC DMA access (assuming 5312 or 231x*/137137+ /* TODO: check other platforms */138138+ reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);139139+ if (to_platform_device(sc->dev)->id == 0)140140+ reg |= AR5K_AR5312_ENABLE_WLAN0;141141+ else142142+ reg |= AR5K_AR5312_ENABLE_WLAN1;143143+ __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);144144+ }145145+146146+ ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);147147+ if (ret != 0) {148148+ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);149149+ ret = -ENODEV;150150+ goto err_free_hw;151151+ }152152+153153+ platform_set_drvdata(pdev, hw);154154+155155+ return 0;156156+157157+ err_free_hw:158158+ ieee80211_free_hw(hw);159159+ platform_set_drvdata(pdev, NULL);160160+ err_out:161161+ return ret;162162+}163163+164164+static int ath_ahb_remove(struct platform_device *pdev)165165+{166166+ struct ar231x_board_config *bcfg = pdev->dev.platform_data;167167+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);168168+ struct ath5k_softc *sc;169169+ u32 reg;170170+171171+ if (!hw)172172+ return 0;173173+174174+ sc = hw->priv;175175+176176+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {177177+ /* Disable WMAC AHB arbitration */178178+ reg = __raw_readl((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);179179+ reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;180180+ __raw_writel(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);181181+ } else {182182+ /*Stop DMA access */183183+ reg = __raw_readl((void __iomem *) AR5K_AR5312_ENABLE);184184+ if (to_platform_device(sc->dev)->id == 0)185185+ reg &= ~AR5K_AR5312_ENABLE_WLAN0;186186+ else187187+ reg &= ~AR5K_AR5312_ENABLE_WLAN1;188188+ __raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);189189+ }190190+191191+ ath5k_deinit_softc(sc);192192+ platform_set_drvdata(pdev, NULL);193193+194194+ return 0;195195+}196196+197197+static struct platform_driver ath_ahb_driver = {198198+ .probe = ath_ahb_probe,199199+ .remove = ath_ahb_remove,200200+ .driver = {201201+ .name = "ar231x-wmac",202202+ .owner = THIS_MODULE,203203+ },204204+};205205+206206+static int __init207207+ath5k_ahb_init(void)208208+{209209+ return platform_driver_register(&ath_ahb_driver);210210+}211211+212212+static void __exit213213+ath5k_ahb_exit(void)214214+{215215+ platform_driver_unregister(&ath_ahb_driver);216216+}217217+218218+module_init(ath5k_ahb_init);219219+module_exit(ath5k_ahb_exit);
+3-3
drivers/net/wireless/ath/ath5k/ani.c
···5858{5959 /* TODO:6060 * ANI documents suggest the following five levels to use, but the HAL6161- * and ath9k use only use the last two levels, making this6161+ * and ath9k use only the last two levels, making this6262 * essentially an on/off option. There *may* be a reason for this (???),6363 * so i stick with the HAL version for now...6464 */6565#if 06666- static const s8 hi[] = { -18, -18, -16, -14, -12 };6766 static const s8 lo[] = { -52, -56, -60, -64, -70 };6767+ static const s8 hi[] = { -18, -18, -16, -14, -12 };6868 static const s8 sz[] = { -34, -41, -48, -55, -62 };6969 static const s8 fr[] = { -70, -72, -75, -78, -80 };7070#else7171- static const s8 sz[] = { -55, -62 };7271 static const s8 lo[] = { -64, -70 };7372 static const s8 hi[] = { -14, -12 };7373+ static const s8 sz[] = { -55, -62 };7474 static const s8 fr[] = { -78, -80 };7575#endif7676 if (level < 0 || level >= ARRAY_SIZE(sz)) {
···9393}94949595/**9696- * ath5k_hw_attach - Check if hw is supported and init the needed structs9696+ * ath5k_hw_init - Check if hw is supported and init the needed structs9797 *9898- * @sc: The &struct ath5k_softc we got from the driver's attach function9898+ * @sc: The &struct ath5k_softc we got from the driver's init_softc function9999 *100100 * Check if the device is supported, perform a POST and initialize the needed101101 * structs. Returns -ENOMEM if we don't have memory for the needed structs,102102 * -ENODEV if the device is not supported or prints an error msg if something103103 * else went wrong.104104 */105105-int ath5k_hw_attach(struct ath5k_softc *sc)105105+int ath5k_hw_init(struct ath5k_softc *sc)106106{107107 struct ath5k_hw *ah = sc->ah;108108 struct ath_common *common = ath5k_hw_common(ah);···115115 * HW information116116 */117117 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;118118- ah->ah_turbo = false;118118+ ah->ah_bwmode = AR5K_BWMODE_DEFAULT;119119 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;120120 ah->ah_imr = 0;121121 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;···128128 /*129129 * Find the mac version130130 */131131- srev = ath5k_hw_reg_read(ah, AR5K_SREV);131131+ ath5k_hw_read_srev(ah);132132+ srev = ah->ah_mac_srev;132133 if (srev < AR5K_SREV_AR5311)133134 ah->ah_version = AR5K_AR5210;134135 else if (srev < AR5K_SREV_AR5212)135136 ah->ah_version = AR5K_AR5211;136137 else137138 ah->ah_version = AR5K_AR5212;139139+140140+ /* Get the MAC revision */141141+ ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);142142+ ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);138143139144 /* Fill the ath5k_hw struct with the needed functions */140145 ret = ath5k_hw_init_desc_functions(ah);···151146 if (ret)152147 goto err;153148154154- /* Get MAC, PHY and RADIO revisions */155155- ah->ah_mac_srev = srev;156156- ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);149149+ /* Get PHY and RADIO revisions */157150 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &158151 0xffffffff;159152 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,···276273 /*277274 * Write PCI-E power save settings278275 */279279- if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {276276+ if ((ah->ah_version == AR5K_AR5212) && pdev && (pdev->is_pcie)) {280277 ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);281278 ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);282279···308305 /* Get misc capabilities */309306 ret = ath5k_hw_set_capabilities(ah);310307 if (ret) {311311- ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",312312- sc->pdev->device);308308+ ATH5K_ERR(sc, "unable to get device capabilities\n");313309 goto err;314310 }315311···348346}349347350348/**351351- * ath5k_hw_detach - Free the ath5k_hw struct349349+ * ath5k_hw_deinit - Free the ath5k_hw struct352350 *353351 * @ah: The &struct ath5k_hw354352 */355355-void ath5k_hw_detach(struct ath5k_hw *ah)353353+void ath5k_hw_deinit(struct ath5k_hw *ah)356354{357355 __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);358356
+276-481
drivers/net/wireless/ath/ath5k/base.c
···4747#include <linux/io.h>4848#include <linux/netdevice.h>4949#include <linux/cache.h>5050-#include <linux/pci.h>5151-#include <linux/pci-aspm.h>5250#include <linux/ethtool.h>5351#include <linux/uaccess.h>5452#include <linux/slab.h>···7880MODULE_LICENSE("Dual BSD/GPL");7981MODULE_VERSION("0.6.0 (EXPERIMENTAL)");80828181-static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);8383+static int ath5k_init(struct ieee80211_hw *hw);8484+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,8585+ bool skip_pcu);8286static int ath5k_beacon_update(struct ieee80211_hw *hw,8387 struct ieee80211_vif *vif);8488static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);85898686-/* Known PCI ids */8787-static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {8888- { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */8989- { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */9090- { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/9191- { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */9292- { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */9393- { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */9494- { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */9595- { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */9696- { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */9797- { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */9898- { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */9999- { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */100100- { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */101101- { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */102102- { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */103103- { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */104104- { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */105105- { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */106106- { 0 }107107-};108108-MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);109109-11090/* Known SREVs */11191static const struct ath5k_srev_name srev_names[] = {9292+#ifdef CONFIG_ATHEROS_AR231X9393+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 },9494+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 },9595+ { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 },9696+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 },9797+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 },9898+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 },9999+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 },100100+#else112101 { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },113102 { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },114103 { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },···114129 { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 },115130 { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 },116131 { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 },132132+#endif117133 { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN },118134 { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },119135 { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },···128142 { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B },129143 { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 },130144 { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 },131131- { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },132132- { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },133145 { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 },134146 { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },147147+#ifdef CONFIG_ATHEROS_AR231X148148+ { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },149149+ { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },150150+#endif135151 { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },136152};137153···185197 BUG_ON(!bf);186198 if (!bf->skb)187199 return;188188- pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,189189- PCI_DMA_TODEVICE);200200+ dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len,201201+ DMA_TO_DEVICE);190202 dev_kfree_skb_any(bf->skb);191203 bf->skb = NULL;192204 bf->skbaddr = 0;···202214 BUG_ON(!bf);203215 if (!bf->skb)204216 return;205205- pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize,206206- PCI_DMA_FROMDEVICE);217217+ dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize,218218+ DMA_FROM_DEVICE);207219 dev_kfree_skb_any(bf->skb);208220 bf->skb = NULL;209221 bf->skbaddr = 0;···221233 return (tsf & ~0x7fff) | rstamp;222234}223235224224-static const char *236236+const char *225237ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)226238{227239 const char *name = "xxxxx";···315327316328 switch (mode) {317329 case AR5K_MODE_11A:318318- case AR5K_MODE_11A_TURBO:319330 /* 1..220, but 2GHz frequencies are filtered by check_channel */320331 size = 220 ;321332 chfreq = CHANNEL_5GHZ;322333 break;323334 case AR5K_MODE_11B:324335 case AR5K_MODE_11G:325325- case AR5K_MODE_11G_TURBO:326336 size = 26;327337 chfreq = CHANNEL_2GHZ;328338 break;···348362 case AR5K_MODE_11A:349363 case AR5K_MODE_11G:350364 channels[count].hw_value = chfreq | CHANNEL_OFDM;351351- break;352352- case AR5K_MODE_11A_TURBO:353353- case AR5K_MODE_11G_TURBO:354354- channels[count].hw_value = chfreq |355355- CHANNEL_OFDM | CHANNEL_TURBO;356365 break;357366 case AR5K_MODE_11B:358367 channels[count].hw_value = CHANNEL_B;···477496 * hardware at the new frequency, and then re-enable478497 * the relevant bits of the h/w.479498 */480480- return ath5k_reset(sc, chan);499499+ return ath5k_reset(sc, chan, true);481500}482501483502static void···634653 return NULL;635654 }636655637637- *skb_addr = pci_map_single(sc->pdev,656656+ *skb_addr = dma_map_single(sc->dev,638657 skb->data, common->rx_bufsize,639639- PCI_DMA_FROMDEVICE);640640- if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {658658+ DMA_FROM_DEVICE);659659+660660+ if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) {641661 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);642662 dev_kfree_skb(skb);643663 return NULL;···734752 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;735753736754 /* XXX endianness */737737- bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,738738- PCI_DMA_TODEVICE);755755+ bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,756756+ DMA_TO_DEVICE);739757740758 rate = ieee80211_get_tx_rate(sc->hw, info);741759 if (!rate) {···815833816834 return 0;817835err_unmap:818818- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);836836+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);819837 return ret;820838}821839···824842\*******************/825843826844static int827827-ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)845845+ath5k_desc_alloc(struct ath5k_softc *sc)828846{829847 struct ath5k_desc *ds;830848 struct ath5k_buf *bf;···835853 /* allocate descriptors */836854 sc->desc_len = sizeof(struct ath5k_desc) *837855 (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);838838- sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);856856+857857+ sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len,858858+ &sc->desc_daddr, GFP_KERNEL);839859 if (sc->desc == NULL) {840860 ATH5K_ERR(sc, "can't allocate descriptors\n");841861 ret = -ENOMEM;···883899884900 return 0;885901err_free:886886- pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);902902+ dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);887903err:888904 sc->desc = NULL;889905 return ret;890906}891907892908static void893893-ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)909909+ath5k_desc_free(struct ath5k_softc *sc)894910{895911 struct ath5k_buf *bf;896912···902918 ath5k_txbuf_free_skb(sc, bf);903919904920 /* Free memory associated with all descriptors */905905- pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);921921+ dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr);906922 sc->desc = NULL;907923 sc->desc_daddr = 0;908924···10471063 return ret;10481064}1049106510501050-static void10511051-ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)10521052-{10531053- struct ath5k_buf *bf, *bf0;10541054-10551055- /*10561056- * NB: this assumes output has been stopped and10571057- * we do not need to block ath5k_tx_tasklet10581058- */10591059- spin_lock_bh(&txq->lock);10601060- list_for_each_entry_safe(bf, bf0, &txq->q, list) {10611061- ath5k_debug_printtxbuf(sc, bf);10621062-10631063- ath5k_txbuf_free_skb(sc, bf);10641064-10651065- spin_lock_bh(&sc->txbuflock);10661066- list_move_tail(&bf->list, &sc->txbuf);10671067- sc->txbuf_len++;10681068- txq->txq_len--;10691069- spin_unlock_bh(&sc->txbuflock);10701070- }10711071- txq->link = NULL;10721072- txq->txq_poll_mark = false;10731073- spin_unlock_bh(&txq->lock);10741074-}10751075-10761076-/*10771077- * Drain the transmit queues and reclaim resources.10661066+/**10671067+ * ath5k_drain_tx_buffs - Empty tx buffers10681068+ *10691069+ * @sc The &struct ath5k_softc10701070+ *10711071+ * Empty tx buffers from all queues in preparation10721072+ * of a reset or during shutdown.10731073+ *10741074+ * NB: this assumes output has been stopped and10751075+ * we do not need to block ath5k_tx_tasklet10781076 */10791077static void10801080-ath5k_txq_cleanup(struct ath5k_softc *sc)10781078+ath5k_drain_tx_buffs(struct ath5k_softc *sc)10811079{10821082- struct ath5k_hw *ah = sc->ah;10831083- unsigned int i;10801080+ struct ath5k_txq *txq;10811081+ struct ath5k_buf *bf, *bf0;10821082+ int i;1084108310851085- /* XXX return value */10861086- if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {10871087- /* don't touch the hardware if marked invalid */10881088- ath5k_hw_stop_tx_dma(ah, sc->bhalq);10891089- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",10901090- ath5k_hw_get_txdp(ah, sc->bhalq));10911091- for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)10921092- if (sc->txqs[i].setup) {10931093- ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);10941094- ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "10951095- "link %p\n",10961096- sc->txqs[i].qnum,10971097- ath5k_hw_get_txdp(ah,10981098- sc->txqs[i].qnum),10991099- sc->txqs[i].link);10841084+ for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) {10851085+ if (sc->txqs[i].setup) {10861086+ txq = &sc->txqs[i];10871087+ spin_lock_bh(&txq->lock);10881088+ list_for_each_entry_safe(bf, bf0, &txq->q, list) {10891089+ ath5k_debug_printtxbuf(sc, bf);10901090+10911091+ ath5k_txbuf_free_skb(sc, bf);10921092+10931093+ spin_lock_bh(&sc->txbuflock);10941094+ list_move_tail(&bf->list, &sc->txbuf);10951095+ sc->txbuf_len++;10961096+ txq->txq_len--;10971097+ spin_unlock_bh(&sc->txbuflock);11001098 }10991099+ txq->link = NULL;11001100+ txq->txq_poll_mark = false;11011101+ spin_unlock_bh(&txq->lock);11021102+ }11011103 }11021102-11031103- for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)11041104- if (sc->txqs[i].setup)11051105- ath5k_txq_drainq(sc, &sc->txqs[i]);11061104}1107110511081106static void···11441178}1145117911461180/*11471147- * Disable the receive h/w in preparation for a reset.11811181+ * Disable the receive logic on PCU (DRU)11821182+ * In preparation for a shutdown.11831183+ *11841184+ * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop11851185+ * does.11481186 */11491187static void11501188ath5k_rx_stop(struct ath5k_softc *sc)11511189{11521190 struct ath5k_hw *ah = sc->ah;1153119111541154- ath5k_hw_stop_rx_pcu(ah); /* disable PCU */11551192 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */11561156- ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */11931193+ ath5k_hw_stop_rx_pcu(ah); /* disable PCU */1157119411581195 ath5k_debug_printrxbuffs(sc, ah);11591196}···15131544 if (!next_skb)15141545 goto next;1515154615161516- pci_unmap_single(sc->pdev, bf->skbaddr,15471547+ dma_unmap_single(sc->dev, bf->skbaddr,15171548 common->rx_bufsize,15181518- PCI_DMA_FROMDEVICE);15491549+ DMA_FROM_DEVICE);1519155015201551 skb_put(skb, rs.rs_datalen);15211552···1678170916791710 skb = bf->skb;16801711 bf->skb = NULL;16811681- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,16821682- PCI_DMA_TODEVICE);17121712+17131713+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len,17141714+ DMA_TO_DEVICE);16831715 ath5k_tx_frame_completed(sc, skb, &ts);16841716 }16851717···17341764 u32 flags;17351765 const int padsize = 0;1736176617371737- bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,17381738- PCI_DMA_TODEVICE);17671767+ bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len,17681768+ DMA_TO_DEVICE);17391769 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "17401770 "skbaddr %llx\n", skb, skb->data, skb->len,17411771 (unsigned long long)bf->skbaddr);17421742- if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {17721772+17731773+ if (dma_mapping_error(sc->dev, bf->skbaddr)) {17431774 ATH5K_ERR(sc, "beacon DMA mapping failed\n");17441775 return -EIO;17451776 }···1792182117931822 return 0;17941823err_unmap:17951795- pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);18241824+ dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE);17961825 return ret;17971826}17981827···19081937 * This should never fail since we check above that no frames19091938 * are still pending on the queue.19101939 */19111911- if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {19401940+ if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) {19121941 ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);19131942 /* NB: hw still stops DMA, so proceed */19141943 }···20772106 } else20782107 ath5k_beacon_update_timers(sc, -1);20792108 } else {20802080- ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);21092109+ ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq);20812110 }2082211120832112 ath5k_hw_set_imr(ah, sc->imask);···21392168 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */21402169}2141217021422142-static irqreturn_t21712171+irqreturn_t21432172ath5k_intr(int irq, void *dev_id)21442173{21452174 struct ath5k_softc *sc = dev_id;···21482177 unsigned int counter = 1000;2149217821502179 if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||21512151- !ath5k_hw_is_intr_pending(ah)))21802180+ ((ath5k_get_bus_type(ah) != ATH_AHB) &&21812181+ !ath5k_hw_is_intr_pending(ah))))21522182 return IRQ_NONE;2153218321542184 do {···22152243 tasklet_schedule(&sc->rf_kill.toggleq);2216224422172245 }22462246+22472247+ if (ath5k_get_bus_type(ah) == ATH_AHB)22482248+ break;22492249+22182250 } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);2219225122202252 if (unlikely(!counter))···23182342 if (needreset) {23192343 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,23202344 "TX queues stuck, resetting\n");23212321- ath5k_reset(sc, sc->curchan);23452345+ ath5k_reset(sc, NULL, true);23222346 }2323234723242348 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,···23292353/*************************\23302354* Initialization routines *23312355\*************************/23562356+23572357+int23582358+ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops)23592359+{23602360+ struct ieee80211_hw *hw = sc->hw;23612361+ struct ath_common *common;23622362+ int ret;23632363+ int csz;23642364+23652365+ /* Initialize driver private data */23662366+ SET_IEEE80211_DEV(hw, sc->dev);23672367+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |23682368+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |23692369+ IEEE80211_HW_SIGNAL_DBM;23702370+23712371+ hw->wiphy->interface_modes =23722372+ BIT(NL80211_IFTYPE_AP) |23732373+ BIT(NL80211_IFTYPE_STATION) |23742374+ BIT(NL80211_IFTYPE_ADHOC) |23752375+ BIT(NL80211_IFTYPE_MESH_POINT);23762376+23772377+ hw->extra_tx_headroom = 2;23782378+ hw->channel_change_time = 5000;23792379+23802380+ /*23812381+ * Mark the device as detached to avoid processing23822382+ * interrupts until setup is complete.23832383+ */23842384+ __set_bit(ATH_STAT_INVALID, sc->status);23852385+23862386+ sc->opmode = NL80211_IFTYPE_STATION;23872387+ sc->bintval = 1000;23882388+ mutex_init(&sc->lock);23892389+ spin_lock_init(&sc->rxbuflock);23902390+ spin_lock_init(&sc->txbuflock);23912391+ spin_lock_init(&sc->block);23922392+23932393+23942394+ /* Setup interrupt handler */23952395+ ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);23962396+ if (ret) {23972397+ ATH5K_ERR(sc, "request_irq failed\n");23982398+ goto err;23992399+ }24002400+24012401+ /* If we passed the test, malloc an ath5k_hw struct */24022402+ sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);24032403+ if (!sc->ah) {24042404+ ret = -ENOMEM;24052405+ ATH5K_ERR(sc, "out of memory\n");24062406+ goto err_irq;24072407+ }24082408+24092409+ sc->ah->ah_sc = sc;24102410+ sc->ah->ah_iobase = sc->iobase;24112411+ common = ath5k_hw_common(sc->ah);24122412+ common->ops = &ath5k_common_ops;24132413+ common->bus_ops = bus_ops;24142414+ common->ah = sc->ah;24152415+ common->hw = hw;24162416+ common->priv = sc;24172417+24182418+ /*24192419+ * Cache line size is used to size and align various24202420+ * structures used to communicate with the hardware.24212421+ */24222422+ ath5k_read_cachesize(common, &csz);24232423+ common->cachelsz = csz << 2; /* convert to bytes */24242424+24252425+ spin_lock_init(&common->cc_lock);24262426+24272427+ /* Initialize device */24282428+ ret = ath5k_hw_init(sc);24292429+ if (ret)24302430+ goto err_free_ah;24312431+24322432+ /* set up multi-rate retry capabilities */24332433+ if (sc->ah->ah_version == AR5K_AR5212) {24342434+ hw->max_rates = 4;24352435+ hw->max_rate_tries = 11;24362436+ }24372437+24382438+ hw->vif_data_size = sizeof(struct ath5k_vif);24392439+24402440+ /* Finish private driver data initialization */24412441+ ret = ath5k_init(hw);24422442+ if (ret)24432443+ goto err_ah;24442444+24452445+ ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",24462446+ ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),24472447+ sc->ah->ah_mac_srev,24482448+ sc->ah->ah_phy_revision);24492449+24502450+ if (!sc->ah->ah_single_chip) {24512451+ /* Single chip radio (!RF5111) */24522452+ if (sc->ah->ah_radio_5ghz_revision &&24532453+ !sc->ah->ah_radio_2ghz_revision) {24542454+ /* No 5GHz support -> report 2GHz radio */24552455+ if (!test_bit(AR5K_MODE_11A,24562456+ sc->ah->ah_capabilities.cap_mode)) {24572457+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",24582458+ ath5k_chip_name(AR5K_VERSION_RAD,24592459+ sc->ah->ah_radio_5ghz_revision),24602460+ sc->ah->ah_radio_5ghz_revision);24612461+ /* No 2GHz support (5110 and some24622462+ * 5Ghz only cards) -> report 5Ghz radio */24632463+ } else if (!test_bit(AR5K_MODE_11B,24642464+ sc->ah->ah_capabilities.cap_mode)) {24652465+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",24662466+ ath5k_chip_name(AR5K_VERSION_RAD,24672467+ sc->ah->ah_radio_5ghz_revision),24682468+ sc->ah->ah_radio_5ghz_revision);24692469+ /* Multiband radio */24702470+ } else {24712471+ ATH5K_INFO(sc, "RF%s multiband radio found"24722472+ " (0x%x)\n",24732473+ ath5k_chip_name(AR5K_VERSION_RAD,24742474+ sc->ah->ah_radio_5ghz_revision),24752475+ sc->ah->ah_radio_5ghz_revision);24762476+ }24772477+ }24782478+ /* Multi chip radio (RF5111 - RF2111) ->24792479+ * report both 2GHz/5GHz radios */24802480+ else if (sc->ah->ah_radio_5ghz_revision &&24812481+ sc->ah->ah_radio_2ghz_revision){24822482+ ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",24832483+ ath5k_chip_name(AR5K_VERSION_RAD,24842484+ sc->ah->ah_radio_5ghz_revision),24852485+ sc->ah->ah_radio_5ghz_revision);24862486+ ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",24872487+ ath5k_chip_name(AR5K_VERSION_RAD,24882488+ sc->ah->ah_radio_2ghz_revision),24892489+ sc->ah->ah_radio_2ghz_revision);24902490+ }24912491+ }24922492+24932493+ ath5k_debug_init_device(sc);24942494+24952495+ /* ready to process interrupts */24962496+ __clear_bit(ATH_STAT_INVALID, sc->status);24972497+24982498+ return 0;24992499+err_ah:25002500+ ath5k_hw_deinit(sc->ah);25012501+err_free_ah:25022502+ kfree(sc->ah);25032503+err_irq:25042504+ free_irq(sc->irq, sc);25052505+err:25062506+ return ret;25072507+}2332250823332509static int23342510ath5k_stop_locked(struct ath5k_softc *sc)···25102382 if (!test_bit(ATH_STAT_INVALID, sc->status)) {25112383 ath5k_led_off(sc);25122384 ath5k_hw_set_imr(ah, 0);25132513- synchronize_irq(sc->pdev->irq);25142514- }25152515- ath5k_txq_cleanup(sc);25162516- if (!test_bit(ATH_STAT_INVALID, sc->status)) {23852385+ synchronize_irq(sc->irq);25172386 ath5k_rx_stop(sc);23872387+ ath5k_hw_dma_stop(ah);23882388+ ath5k_drain_tx_buffs(sc);25182389 ath5k_hw_phy_disable(ah);25192390 }25202391···25212394}2522239525232396static int25242524-ath5k_init(struct ath5k_softc *sc)23972397+ath5k_init_hw(struct ath5k_softc *sc)25252398{25262399 struct ath5k_hw *ah = sc->ah;25272400 struct ath_common *common = ath5k_hw_common(ah);···25502423 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |25512424 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;2552242525532553- ret = ath5k_reset(sc, NULL);24262426+ ret = ath5k_reset(sc, NULL, false);25542427 if (ret)25552428 goto done;25562429···25632436 for (i = 0; i < common->keymax; i++)25642437 ath_hw_keyreset(common, (u16) i);2565243825662566- ath5k_hw_set_ack_bitrate_high(ah, true);24392439+ /* Use higher rates for acks instead of base24402440+ * rate */24412441+ ah->ah_ack_bitrate_high = true;2567244225682443 for (i = 0; i < ARRAY_SIZE(sc->bslot); i++)25692444 sc->bslot[i] = NULL;···26492520 * This should be called with sc->lock.26502521 */26512522static int26522652-ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)25232523+ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,25242524+ bool skip_pcu)26532525{26542526 struct ath5k_hw *ah = sc->ah;26552527 int ret;···26582528 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");2659252926602530 ath5k_hw_set_imr(ah, 0);26612661- synchronize_irq(sc->pdev->irq);25312531+ synchronize_irq(sc->irq);26622532 stop_tasklets(sc);2663253326642534 if (chan) {26652665- ath5k_txq_cleanup(sc);26662666- ath5k_rx_stop(sc);25352535+ ath5k_drain_tx_buffs(sc);2667253626682537 sc->curchan = chan;26692538 sc->curband = &sc->sbands[chan->band];26702539 }26712671- ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);25402540+ ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,25412541+ skip_pcu);26722542 if (ret) {26732543 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);26742544 goto err;···27142584 reset_work);2715258527162586 mutex_lock(&sc->lock);27172717- ath5k_reset(sc, sc->curchan);25872587+ ath5k_reset(sc, NULL, true);27182588 mutex_unlock(&sc->lock);27192589}2720259027212591static int27222722-ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)25922592+ath5k_init(struct ieee80211_hw *hw)27232593{25942594+27242595 struct ath5k_softc *sc = hw->priv;27252596 struct ath5k_hw *ah = sc->ah;27262597 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);···27292598 u8 mac[ETH_ALEN] = {};27302599 int ret;2731260027322732- ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);2733260127342602 /*27352603 * Check if the MAC has multi-rate retry support.···27652635 /*27662636 * Allocate tx+rx descriptors and populate the lists.27672637 */27682768- ret = ath5k_desc_alloc(sc, pdev);26382638+ ret = ath5k_desc_alloc(sc);27692639 if (ret) {27702640 ATH5K_ERR(sc, "can't allocate descriptors\n");27712641 goto err;···2829269928302700 ret = ath5k_eeprom_read_mac(ah, mac);28312701 if (ret) {28322832- ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",28332833- sc->pdev->device);27022702+ ATH5K_ERR(sc, "unable to read address from EEPROM\n");28342703 goto err_queues;28352704 }28362705···28642735err_bhal:28652736 ath5k_hw_release_tx_queue(ah, sc->bhalq);28662737err_desc:28672867- ath5k_desc_free(sc, pdev);27382738+ ath5k_desc_free(sc);28682739err:28692740 return ret;28702741}2871274228722872-static void28732873-ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)27432743+void27442744+ath5k_deinit_softc(struct ath5k_softc *sc)28742745{28752875- struct ath5k_softc *sc = hw->priv;27462746+ struct ieee80211_hw *hw = sc->hw;2876274728772748 /*28782749 * NB: the order of these is important:···28872758 * XXX: ??? detach ath5k_hw ???28882759 * Other than that, it's straightforward...28892760 */27612761+ ath5k_debug_finish_device(sc);28902762 ieee80211_unregister_hw(hw);28912891- ath5k_desc_free(sc, pdev);27632763+ ath5k_desc_free(sc);28922764 ath5k_txq_release(sc);28932765 ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);28942766 ath5k_unregister_leds(sc);···29002770 * returns because we'll get called back to reclaim node29012771 * state and potentially want to use them.29022772 */27732773+ ath5k_hw_deinit(sc->ah);27742774+ free_irq(sc->irq, sc);29032775}2904277629052777/********************\···2924279229252793static int ath5k_start(struct ieee80211_hw *hw)29262794{29272927- return ath5k_init(hw->priv);27952795+ return ath5k_init_hw(hw->priv);29282796}2929279729302798static void ath5k_stop(struct ieee80211_hw *hw)···35693437 return 0;35703438}3571343935723572-static const struct ieee80211_ops ath5k_hw_ops = {34403440+const struct ieee80211_ops ath5k_hw_ops = {35733441 .tx = ath5k_tx,35743442 .start = ath5k_start,35753443 .stop = ath5k_stop,···35923460 .set_antenna = ath5k_set_antenna,35933461 .get_antenna = ath5k_get_antenna,35943462};35953595-35963596-/********************\35973597-* PCI Initialization *35983598-\********************/35993599-36003600-static int __devinit36013601-ath5k_pci_probe(struct pci_dev *pdev,36023602- const struct pci_device_id *id)36033603-{36043604- void __iomem *mem;36053605- struct ath5k_softc *sc;36063606- struct ath_common *common;36073607- struct ieee80211_hw *hw;36083608- int ret;36093609- u8 csz;36103610-36113611- /*36123612- * L0s needs to be disabled on all ath5k cards.36133613- *36143614- * For distributions shipping with CONFIG_PCIEASPM (this will be enabled36153615- * by default in the future in 2.6.36) this will also mean both L1 and36163616- * L0s will be disabled when a pre 1.1 PCIe device is detected. We do36173617- * know L1 works correctly even for all ath5k pre 1.1 PCIe devices36183618- * though but cannot currently undue the effect of a blacklist, for36193619- * details you can read pcie_aspm_sanity_check() and see how it adjusts36203620- * the device link capability.36213621- *36223622- * It may be possible in the future to implement some PCI API to allow36233623- * drivers to override blacklists for pre 1.1 PCIe but for now it is36243624- * best to accept that both L0s and L1 will be disabled completely for36253625- * distributions shipping with CONFIG_PCIEASPM rather than having this36263626- * issue present. Motivation for adding this new API will be to help36273627- * with power consumption for some of these devices.36283628- */36293629- pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);36303630-36313631- ret = pci_enable_device(pdev);36323632- if (ret) {36333633- dev_err(&pdev->dev, "can't enable device\n");36343634- goto err;36353635- }36363636-36373637- /* XXX 32-bit addressing only */36383638- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));36393639- if (ret) {36403640- dev_err(&pdev->dev, "32-bit DMA not available\n");36413641- goto err_dis;36423642- }36433643-36443644- /*36453645- * Cache line size is used to size and align various36463646- * structures used to communicate with the hardware.36473647- */36483648- pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);36493649- if (csz == 0) {36503650- /*36513651- * Linux 2.4.18 (at least) writes the cache line size36523652- * register as a 16-bit wide register which is wrong.36533653- * We must have this setup properly for rx buffer36543654- * DMA to work so force a reasonable value here if it36553655- * comes up zero.36563656- */36573657- csz = L1_CACHE_BYTES >> 2;36583658- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);36593659- }36603660- /*36613661- * The default setting of latency timer yields poor results,36623662- * set it to the value used by other systems. It may be worth36633663- * tweaking this setting more.36643664- */36653665- pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);36663666-36673667- /* Enable bus mastering */36683668- pci_set_master(pdev);36693669-36703670- /*36713671- * Disable the RETRY_TIMEOUT register (0x41) to keep36723672- * PCI Tx retries from interfering with C3 CPU state.36733673- */36743674- pci_write_config_byte(pdev, 0x41, 0);36753675-36763676- ret = pci_request_region(pdev, 0, "ath5k");36773677- if (ret) {36783678- dev_err(&pdev->dev, "cannot reserve PCI memory region\n");36793679- goto err_dis;36803680- }36813681-36823682- mem = pci_iomap(pdev, 0, 0);36833683- if (!mem) {36843684- dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;36853685- ret = -EIO;36863686- goto err_reg;36873687- }36883688-36893689- /*36903690- * Allocate hw (mac80211 main struct)36913691- * and hw->priv (driver private data)36923692- */36933693- hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);36943694- if (hw == NULL) {36953695- dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");36963696- ret = -ENOMEM;36973697- goto err_map;36983698- }36993699-37003700- dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));37013701-37023702- /* Initialize driver private data */37033703- SET_IEEE80211_DEV(hw, &pdev->dev);37043704- hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |37053705- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |37063706- IEEE80211_HW_SIGNAL_DBM;37073707-37083708- hw->wiphy->interface_modes =37093709- BIT(NL80211_IFTYPE_AP) |37103710- BIT(NL80211_IFTYPE_STATION) |37113711- BIT(NL80211_IFTYPE_ADHOC) |37123712- BIT(NL80211_IFTYPE_MESH_POINT);37133713-37143714- hw->extra_tx_headroom = 2;37153715- hw->channel_change_time = 5000;37163716- sc = hw->priv;37173717- sc->hw = hw;37183718- sc->pdev = pdev;37193719-37203720- /*37213721- * Mark the device as detached to avoid processing37223722- * interrupts until setup is complete.37233723- */37243724- __set_bit(ATH_STAT_INVALID, sc->status);37253725-37263726- sc->iobase = mem; /* So we can unmap it on detach */37273727- sc->opmode = NL80211_IFTYPE_STATION;37283728- sc->bintval = 1000;37293729- mutex_init(&sc->lock);37303730- spin_lock_init(&sc->rxbuflock);37313731- spin_lock_init(&sc->txbuflock);37323732- spin_lock_init(&sc->block);37333733-37343734- /* Set private data */37353735- pci_set_drvdata(pdev, sc);37363736-37373737- /* Setup interrupt handler */37383738- ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);37393739- if (ret) {37403740- ATH5K_ERR(sc, "request_irq failed\n");37413741- goto err_free;37423742- }37433743-37443744- /* If we passed the test, malloc an ath5k_hw struct */37453745- sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);37463746- if (!sc->ah) {37473747- ret = -ENOMEM;37483748- ATH5K_ERR(sc, "out of memory\n");37493749- goto err_irq;37503750- }37513751-37523752- sc->ah->ah_sc = sc;37533753- sc->ah->ah_iobase = sc->iobase;37543754- common = ath5k_hw_common(sc->ah);37553755- common->ops = &ath5k_common_ops;37563756- common->ah = sc->ah;37573757- common->hw = hw;37583758- common->cachelsz = csz << 2; /* convert to bytes */37593759- spin_lock_init(&common->cc_lock);37603760-37613761- /* Initialize device */37623762- ret = ath5k_hw_attach(sc);37633763- if (ret) {37643764- goto err_free_ah;37653765- }37663766-37673767- /* set up multi-rate retry capabilities */37683768- if (sc->ah->ah_version == AR5K_AR5212) {37693769- hw->max_rates = 4;37703770- hw->max_rate_tries = 11;37713771- }37723772-37733773- hw->vif_data_size = sizeof(struct ath5k_vif);37743774-37753775- /* Finish private driver data initialization */37763776- ret = ath5k_attach(pdev, hw);37773777- if (ret)37783778- goto err_ah;37793779-37803780- ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",37813781- ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),37823782- sc->ah->ah_mac_srev,37833783- sc->ah->ah_phy_revision);37843784-37853785- if (!sc->ah->ah_single_chip) {37863786- /* Single chip radio (!RF5111) */37873787- if (sc->ah->ah_radio_5ghz_revision &&37883788- !sc->ah->ah_radio_2ghz_revision) {37893789- /* No 5GHz support -> report 2GHz radio */37903790- if (!test_bit(AR5K_MODE_11A,37913791- sc->ah->ah_capabilities.cap_mode)) {37923792- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",37933793- ath5k_chip_name(AR5K_VERSION_RAD,37943794- sc->ah->ah_radio_5ghz_revision),37953795- sc->ah->ah_radio_5ghz_revision);37963796- /* No 2GHz support (5110 and some37973797- * 5Ghz only cards) -> report 5Ghz radio */37983798- } else if (!test_bit(AR5K_MODE_11B,37993799- sc->ah->ah_capabilities.cap_mode)) {38003800- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",38013801- ath5k_chip_name(AR5K_VERSION_RAD,38023802- sc->ah->ah_radio_5ghz_revision),38033803- sc->ah->ah_radio_5ghz_revision);38043804- /* Multiband radio */38053805- } else {38063806- ATH5K_INFO(sc, "RF%s multiband radio found"38073807- " (0x%x)\n",38083808- ath5k_chip_name(AR5K_VERSION_RAD,38093809- sc->ah->ah_radio_5ghz_revision),38103810- sc->ah->ah_radio_5ghz_revision);38113811- }38123812- }38133813- /* Multi chip radio (RF5111 - RF2111) ->38143814- * report both 2GHz/5GHz radios */38153815- else if (sc->ah->ah_radio_5ghz_revision &&38163816- sc->ah->ah_radio_2ghz_revision){38173817- ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",38183818- ath5k_chip_name(AR5K_VERSION_RAD,38193819- sc->ah->ah_radio_5ghz_revision),38203820- sc->ah->ah_radio_5ghz_revision);38213821- ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",38223822- ath5k_chip_name(AR5K_VERSION_RAD,38233823- sc->ah->ah_radio_2ghz_revision),38243824- sc->ah->ah_radio_2ghz_revision);38253825- }38263826- }38273827-38283828- ath5k_debug_init_device(sc);38293829-38303830- /* ready to process interrupts */38313831- __clear_bit(ATH_STAT_INVALID, sc->status);38323832-38333833- return 0;38343834-err_ah:38353835- ath5k_hw_detach(sc->ah);38363836-err_free_ah:38373837- kfree(sc->ah);38383838-err_irq:38393839- free_irq(pdev->irq, sc);38403840-err_free:38413841- ieee80211_free_hw(hw);38423842-err_map:38433843- pci_iounmap(pdev, mem);38443844-err_reg:38453845- pci_release_region(pdev, 0);38463846-err_dis:38473847- pci_disable_device(pdev);38483848-err:38493849- return ret;38503850-}38513851-38523852-static void __devexit38533853-ath5k_pci_remove(struct pci_dev *pdev)38543854-{38553855- struct ath5k_softc *sc = pci_get_drvdata(pdev);38563856-38573857- ath5k_debug_finish_device(sc);38583858- ath5k_detach(pdev, sc->hw);38593859- ath5k_hw_detach(sc->ah);38603860- kfree(sc->ah);38613861- free_irq(pdev->irq, sc);38623862- pci_iounmap(pdev, sc->iobase);38633863- pci_release_region(pdev, 0);38643864- pci_disable_device(pdev);38653865- ieee80211_free_hw(sc->hw);38663866-}38673867-38683868-#ifdef CONFIG_PM_SLEEP38693869-static int ath5k_pci_suspend(struct device *dev)38703870-{38713871- struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));38723872-38733873- ath5k_led_off(sc);38743874- return 0;38753875-}38763876-38773877-static int ath5k_pci_resume(struct device *dev)38783878-{38793879- struct pci_dev *pdev = to_pci_dev(dev);38803880- struct ath5k_softc *sc = pci_get_drvdata(pdev);38813881-38823882- /*38833883- * Suspend/Resume resets the PCI configuration space, so we have to38843884- * re-disable the RETRY_TIMEOUT register (0x41) to keep38853885- * PCI Tx retries from interfering with C3 CPU state38863886- */38873887- pci_write_config_byte(pdev, 0x41, 0);38883888-38893889- ath5k_led_enable(sc);38903890- return 0;38913891-}38923892-38933893-static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);38943894-#define ATH5K_PM_OPS (&ath5k_pm_ops)38953895-#else38963896-#define ATH5K_PM_OPS NULL38973897-#endif /* CONFIG_PM_SLEEP */38983898-38993899-static struct pci_driver ath5k_pci_driver = {39003900- .name = KBUILD_MODNAME,39013901- .id_table = ath5k_pci_id_table,39023902- .probe = ath5k_pci_probe,39033903- .remove = __devexit_p(ath5k_pci_remove),39043904- .driver.pm = ATH5K_PM_OPS,39053905-};39063906-39073907-/*39083908- * Module init/exit functions39093909- */39103910-static int __init39113911-init_ath5k_pci(void)39123912-{39133913- int ret;39143914-39153915- ret = pci_register_driver(&ath5k_pci_driver);39163916- if (ret) {39173917- printk(KERN_ERR "ath5k_pci: can't register pci driver\n");39183918- return ret;39193919- }39203920-39213921- return 0;39223922-}39233923-39243924-static void __exit39253925-exit_ath5k_pci(void)39263926-{39273927- pci_unregister_driver(&ath5k_pci_driver);39283928-}39293929-39303930-module_init(init_ath5k_pci);39313931-module_exit(exit_ath5k_pci);
+4-1
drivers/net/wireless/ath/ath5k/base.h
···169169/* Software Carrier, keeps track of the driver state170170 * associated with an instance of a device */171171struct ath5k_softc {172172- struct pci_dev *pdev; /* for dma mapping */172172+ struct pci_dev *pdev;173173+ struct device *dev; /* for dma mapping */174174+ int irq;175175+ u16 devid;173176 void __iomem *iobase; /* address of the device */174177 struct mutex lock; /* dev-level lock */175178 struct ieee80211_hw *hw; /* IEEE 802.11 common */
-6
drivers/net/wireless/ath/ath5k/caps.c
···49495050 /* Set supported modes */5151 __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);5252- __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);5352 } else {5453 /*5554 * XXX The tranceiver supports frequencies from 4920 to 6100GHz···7374 /* Set supported modes */7475 __set_bit(AR5K_MODE_11A,7576 ah->ah_capabilities.cap_mode);7676- __set_bit(AR5K_MODE_11A_TURBO,7777- ah->ah_capabilities.cap_mode);7878- if (ah->ah_version == AR5K_AR5212)7979- __set_bit(AR5K_MODE_11G_TURBO,8080- ah->ah_capabilities.cap_mode);8177 }82788379 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
···2626#include "debug.h"2727#include "base.h"28282929-/*3030- * TX Descriptors3131- */2929+3030+/************************\3131+* TX Control descriptors *3232+\************************/32333334/*3435 * Initialize the 2-word tx control descriptor on 5210/5211···336335 return 0;337336}338337338338+339339+/***********************\340340+* TX Status descriptors *341341+\***********************/342342+339343/*340344 * Proccess the tx status descriptor on 5210/5211341345 */···482476 return 0;483477}484478485485-/*486486- * RX Descriptors487487- */479479+480480+/****************\481481+* RX Descriptors *482482+\****************/488483489484/*490485 * Initialize an rx control descriptor···672665 }673666 return 0;674667}668668+669669+670670+/********\671671+* Attach *672672+\********/675673676674/*677675 * Init function pointers inside ath5k_hw struct
+168-12
drivers/net/wireless/ath/ath5k/dma.c
···3737#include "debug.h"3838#include "base.h"39394040+4041/*********\4142* Receive *4243\*********/···5857 *5958 * @ah: The &struct ath5k_hw6059 */6161-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)6060+static int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)6261{6362 unsigned int i;6463···7069 for (i = 1000; i > 0 &&7170 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;7271 i--)7373- udelay(10);7272+ udelay(100);7373+7474+ if (i)7575+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,7676+ "failed to stop RX DMA !\n");74777578 return i ? 0 : -EBUSY;7679}···9590 * @ah: The &struct ath5k_hw9691 * @phys_addr: RX descriptor address9792 *9898- * XXX: Should we check if rx is enabled before setting rxdp ?9393+ * Returns -EIO if rx is active9994 */100100-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)9595+int ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)10196{9797+ if (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) {9898+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,9999+ "tried to set RXDP while rx was active !\n");100100+ return -EIO;101101+ }102102+102103 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);104104+ return 0;103105}104106105107···137125138126 /* Return if queue is declared inactive */139127 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)140140- return -EIO;128128+ return -EINVAL;141129142130 if (ah->ah_version == AR5K_AR5210) {143131 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);···185173 *186174 * Stop DMA transmit on a specific hw queue and drain queue so we don't187175 * have any pending frames. Returns -EBUSY if we still have pending frames,188188- * -EINVAL if queue number is out of range.176176+ * -EINVAL if queue number is out of range or inactive.189177 *190178 */191191-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)179179+static int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)192180{193181 unsigned int i = 40;194182 u32 tx_queue, pending;···197185198186 /* Return if queue is declared inactive */199187 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)200200- return -EIO;188188+ return -EINVAL;201189202190 if (ah->ah_version == AR5K_AR5210) {203191 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);···223211 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);224212 ath5k_hw_reg_read(ah, AR5K_CR);225213 } else {214214+215215+ /*216216+ * Enable DCU early termination to quickly217217+ * flush any pending frames from QCU218218+ */219219+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),220220+ AR5K_QCU_MISC_DCU_EARLY);221221+226222 /*227223 * Schedule TX disable and wait until queue is empty228224 */229225 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);230226231231- /*Check for pending frames*/227227+ /* Wait for queue to stop */228228+ for (i = 1000; i > 0 &&229229+ (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue) != 0);230230+ i--)231231+ udelay(100);232232+233233+ if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))234234+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,235235+ "queue %i didn't stop !\n", queue);236236+237237+ /* Check for pending frames */238238+ i = 1000;232239 do {233240 pending = ath5k_hw_reg_read(ah,234241 AR5K_QUEUE_STATUS(queue)) &···278247 AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);279248280249 /* Wait a while and disable mechanism */281281- udelay(200);250250+ udelay(400);282251 AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,283252 AR5K_QUIET_CTL1_QT_EN);284253285254 /* Re-check for pending frames */286286- i = 40;255255+ i = 100;287256 do {288257 pending = ath5k_hw_reg_read(ah,289258 AR5K_QUEUE_STATUS(queue)) &···293262294263 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,295264 AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);265265+266266+ if (pending)267267+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,268268+ "quiet mechanism didn't work q:%i !\n",269269+ queue);296270 }271271+272272+ /*273273+ * Disable DCU early termination274274+ */275275+ AR5K_REG_DISABLE_BITS(ah, AR5K_QUEUE_MISC(queue),276276+ AR5K_QCU_MISC_DCU_EARLY);297277298278 /* Clear register */299279 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);300300- if (pending)280280+ if (pending) {281281+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,282282+ "tx dma didn't stop (q:%i, frm:%i) !\n",283283+ queue, pending);301284 return -EBUSY;285285+ }302286 }303287304288 /* TODO: Check for success on 5210 else return error */289289+ return 0;290290+}291291+292292+/**293293+ * ath5k_hw_stop_beacon_queue - Stop beacon queue294294+ *295295+ * @ah The &struct ath5k_hw296296+ * @queue The queue number297297+ *298298+ * Returns -EIO if queue didn't stop299299+ */300300+int ath5k_hw_stop_beacon_queue(struct ath5k_hw *ah, unsigned int queue)301301+{302302+ int ret;303303+ ret = ath5k_hw_stop_tx_dma(ah, queue);304304+ if (ret) {305305+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_DMA,306306+ "beacon queue didn't stop !\n");307307+ return -EIO;308308+ }305309 return 0;306310}307311···492426493427 return ret;494428}429429+495430496431/*******************\497432* Interrupt masking *···755688 return old_mask;756689}757690691691+692692+/********************\693693+ Init/Stop functions694694+\********************/695695+696696+/**697697+ * ath5k_hw_dma_init - Initialize DMA unit698698+ *699699+ * @ah: The &struct ath5k_hw700700+ *701701+ * Set DMA size and pre-enable interrupts702702+ * (driver handles tx/rx buffer setup and703703+ * dma start/stop)704704+ *705705+ * XXX: Save/restore RXDP/TXDP registers ?706706+ */707707+void ath5k_hw_dma_init(struct ath5k_hw *ah)708708+{709709+ /*710710+ * Set Rx/Tx DMA Configuration711711+ *712712+ * Set standard DMA size (128). Note that713713+ * a DMA size of 512 causes rx overruns and tx errors714714+ * on pci-e cards (tested on 5424 but since rx overruns715715+ * also occur on 5416/5418 with madwifi we set 128716716+ * for all PCI-E cards to be safe).717717+ *718718+ * XXX: need to check 5210 for this719719+ * TODO: Check out tx triger level, it's always 64 on dumps but I720720+ * guess we can tweak it and see how it goes ;-)721721+ */722722+ if (ah->ah_version != AR5K_AR5210) {723723+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,724724+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);725725+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,726726+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);727727+ }728728+729729+ /* Pre-enable interrupts on 5211/5212*/730730+ if (ah->ah_version != AR5K_AR5210)731731+ ath5k_hw_set_imr(ah, ah->ah_imr);732732+733733+}734734+735735+/**736736+ * ath5k_hw_dma_stop - stop DMA unit737737+ *738738+ * @ah: The &struct ath5k_hw739739+ *740740+ * Stop tx/rx DMA and interrupts. Returns741741+ * -EBUSY if tx or rx dma failed to stop.742742+ *743743+ * XXX: Sometimes DMA unit hangs and we have744744+ * stuck frames on tx queues, only a reset745745+ * can fix that.746746+ */747747+int ath5k_hw_dma_stop(struct ath5k_hw *ah)748748+{749749+ int i, qmax, err;750750+ err = 0;751751+752752+ /* Disable interrupts */753753+ ath5k_hw_set_imr(ah, 0);754754+755755+ /* Stop rx dma */756756+ err = ath5k_hw_stop_rx_dma(ah);757757+ if (err)758758+ return err;759759+760760+ /* Clear any pending interrupts761761+ * and disable tx dma */762762+ if (ah->ah_version != AR5K_AR5210) {763763+ ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);764764+ qmax = AR5K_NUM_TX_QUEUES;765765+ } else {766766+ /* PISR/SISR Not available on 5210 */767767+ ath5k_hw_reg_read(ah, AR5K_ISR);768768+ qmax = AR5K_NUM_TX_QUEUES_NOQCU;769769+ }770770+771771+ for (i = 0; i < qmax; i++) {772772+ err = ath5k_hw_stop_tx_dma(ah, i);773773+ /* -EINVAL -> queue inactive */774774+ if (err != -EINVAL)775775+ return err;776776+ }777777+778778+ return err;779779+}
+55-72
drivers/net/wireless/ath/ath5k/eeprom.c
···2828#include "debug.h"2929#include "base.h"30303131-/*3232- * Read from eeprom3333- */3434-static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)3535-{3636- u32 status, timeout;37313838- /*3939- * Initialize EEPROM access4040- */4141- if (ah->ah_version == AR5K_AR5210) {4242- AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);4343- (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));4444- } else {4545- ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);4646- AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,4747- AR5K_EEPROM_CMD_READ);4848- }4949-5050- for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {5151- status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);5252- if (status & AR5K_EEPROM_STAT_RDDONE) {5353- if (status & AR5K_EEPROM_STAT_RDERR)5454- return -EIO;5555- *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &5656- 0xffff);5757- return 0;5858- }5959- udelay(15);6060- }6161-6262- return -ETIMEDOUT;6363-}3232+/******************\3333+* Helper functions *3434+\******************/64356536/*6637 * Translate binary channel representation in EEPROM to frequency6738 */6839static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,6969- unsigned int mode)4040+ unsigned int mode)7041{7142 u16 val;7243···59886089 return val;6190}9191+9292+9393+/*********\9494+* Parsers *9595+\*********/62966397/*6498 * Initialize eeprom & capabilities structs···174198 *175199 * XXX: Serdes values seem to be fixed so176200 * no need to read them here, we write them177177- * during ath5k_hw_attach */201201+ * during ath5k_hw_init */178202 AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);179203 ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?180204 true : false;···622646623647 return 0;624648}649649+625650626651/*627652 * Read power calibration for RF5111 chips···14911514 return 0;14921515}1493151615171517+14941518/*14951519 * Read per channel calibration info from EEPROM14961520 *···15831605 }1584160615851607 return 0;15861586-}15871587-15881588-void15891589-ath5k_eeprom_detach(struct ath5k_hw *ah)15901590-{15911591- u8 mode;15921592-15931593- for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)15941594- ath5k_eeprom_free_pcal_info(ah, mode);15951608}1596160915971610/* Read conformance test limits used for regulatory control */···17261757}1727175817281759/*17601760+ * Read the MAC address from eeprom17611761+ */17621762+int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)17631763+{17641764+ u8 mac_d[ETH_ALEN] = {};17651765+ u32 total, offset;17661766+ u16 data;17671767+ int octet, ret;17681768+17691769+ ret = ath5k_hw_nvram_read(ah, 0x20, &data);17701770+ if (ret)17711771+ return ret;17721772+17731773+ for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {17741774+ ret = ath5k_hw_nvram_read(ah, offset, &data);17751775+ if (ret)17761776+ return ret;17771777+17781778+ total += data;17791779+ mac_d[octet + 1] = data & 0xff;17801780+ mac_d[octet] = data >> 8;17811781+ octet += 2;17821782+ }17831783+17841784+ if (!total || total == 3 * 0xffff)17851785+ return -EINVAL;17861786+17871787+ memcpy(mac, mac_d, ETH_ALEN);17881788+17891789+ return 0;17901790+}17911791+17921792+17931793+/***********************\17941794+* Init/Detach functions *17951795+\***********************/17961796+17971797+/*17291798 * Initialize eeprom data structure17301799 */17311800int···17941787 return 0;17951788}1796178917971797-/*17981798- * Read the MAC address from eeprom17991799- */18001800-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)17901790+void17911791+ath5k_eeprom_detach(struct ath5k_hw *ah)18011792{18021802- u8 mac_d[ETH_ALEN] = {};18031803- u32 total, offset;18041804- u16 data;18051805- int octet, ret;17931793+ u8 mode;1806179418071807- ret = ath5k_hw_eeprom_read(ah, 0x20, &data);18081808- if (ret)18091809- return ret;18101810-18111811- for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {18121812- ret = ath5k_hw_eeprom_read(ah, offset, &data);18131813- if (ret)18141814- return ret;18151815-18161816- total += data;18171817- mac_d[octet + 1] = data & 0xff;18181818- mac_d[octet] = data >> 8;18191819- octet += 2;18201820- }18211821-18221822- if (!total || total == 3 * 0xffff)18231823- return -EINVAL;18241824-18251825- memcpy(mac, mac_d, ETH_ALEN);18261826-18271827- return 0;17951795+ for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)17961796+ ath5k_eeprom_free_pcal_info(ah, mode);18281797}
+1-1
drivers/net/wireless/ath/ath5k/eeprom.h
···241241#define AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz 6250242242243243#define AR5K_EEPROM_READ(_o, _v) do { \244244- ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \244244+ ret = ath5k_hw_nvram_read(ah, (_o), &(_v)); \245245 if (ret) \246246 return ret; \247247} while (0)
···133133 led->led_dev.default_trigger = trigger;134134 led->led_dev.brightness_set = ath5k_led_brightness_set;135135136136- err = led_classdev_register(&sc->pdev->dev, &led->led_dev);136136+ err = led_classdev_register(sc->dev, &led->led_dev);137137 if (err) {138138 ATH5K_WARN(sc, "could not register LED %s\n", name);139139 led->sc = NULL;···161161{162162 int ret = 0;163163 struct ieee80211_hw *hw = sc->hw;164164+#ifndef CONFIG_ATHEROS_AR231X164165 struct pci_dev *pdev = sc->pdev;166166+#endif165167 char name[ATH5K_LED_MAX_NAME_LEN + 1];166168 const struct pci_device_id *match;167169170170+ if (!sc->pdev)171171+ return 0;172172+173173+#ifdef CONFIG_ATHEROS_AR231X174174+ match = NULL;175175+#else168176 match = pci_match_id(&ath5k_led_devices[0], pdev);177177+#endif169178 if (match) {170179 __set_bit(ATH_STAT_LEDSOFT, sc->status);171180 sc->led_pin = ATH_PIN(match->driver_data);
+326
drivers/net/wireless/ath/ath5k/pci.c
···11+/*22+ * Copyright (c) 2008-2009 Atheros Communications Inc.33+ *44+ * Permission to use, copy, modify, and/or distribute this software for any55+ * purpose with or without fee is hereby granted, provided that the above66+ * copyright notice and this permission notice appear in all copies.77+ *88+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES99+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1010+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR1111+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1212+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1313+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1414+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1515+ */1616+1717+#include <linux/nl80211.h>1818+#include <linux/pci.h>1919+#include <linux/pci-aspm.h>2020+#include "../ath.h"2121+#include "ath5k.h"2222+#include "debug.h"2323+#include "base.h"2424+#include "reg.h"2525+2626+/* Known PCI ids */2727+static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = {2828+ { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */2929+ { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */3030+ { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/3131+ { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */3232+ { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */3333+ { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */3434+ { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */3535+ { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */3636+ { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */3737+ { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */3838+ { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */3939+ { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */4040+ { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */4141+ { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */4242+ { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */4343+ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */4444+ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */4545+ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */4646+ { 0 }4747+};4848+4949+/* return bus cachesize in 4B word units */5050+static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)5151+{5252+ struct ath5k_softc *sc = (struct ath5k_softc *) common->priv;5353+ u8 u8tmp;5454+5555+ pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);5656+ *csz = (int)u8tmp;5757+5858+ /*5959+ * This check was put in to avoid "unplesant" consequences if6060+ * the bootrom has not fully initialized all PCI devices.6161+ * Sometimes the cache line size register is not set6262+ */6363+6464+ if (*csz == 0)6565+ *csz = L1_CACHE_BYTES >> 2; /* Use the default size */6666+}6767+6868+/*6969+ * Read from eeprom7070+ */7171+bool ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)7272+{7373+ struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;7474+ u32 status, timeout;7575+7676+ /*7777+ * Initialize EEPROM access7878+ */7979+ if (ah->ah_version == AR5K_AR5210) {8080+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);8181+ (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));8282+ } else {8383+ ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);8484+ AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,8585+ AR5K_EEPROM_CMD_READ);8686+ }8787+8888+ for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {8989+ status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);9090+ if (status & AR5K_EEPROM_STAT_RDDONE) {9191+ if (status & AR5K_EEPROM_STAT_RDERR)9292+ return -EIO;9393+ *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &9494+ 0xffff);9595+ return 0;9696+ }9797+ udelay(15);9898+ }9999+100100+ return -ETIMEDOUT;101101+}102102+103103+int ath5k_hw_read_srev(struct ath5k_hw *ah)104104+{105105+ ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV);106106+ return 0;107107+}108108+109109+/* Common ath_bus_opts structure */110110+static const struct ath_bus_ops ath_pci_bus_ops = {111111+ .ath_bus_type = ATH_PCI,112112+ .read_cachesize = ath5k_pci_read_cachesize,113113+ .eeprom_read = ath5k_pci_eeprom_read,114114+};115115+116116+/********************\117117+* PCI Initialization *118118+\********************/119119+120120+static int __devinit121121+ath5k_pci_probe(struct pci_dev *pdev,122122+ const struct pci_device_id *id)123123+{124124+ void __iomem *mem;125125+ struct ath5k_softc *sc;126126+ struct ieee80211_hw *hw;127127+ int ret;128128+ u8 csz;129129+130130+ /*131131+ * L0s needs to be disabled on all ath5k cards.132132+ *133133+ * For distributions shipping with CONFIG_PCIEASPM (this will be enabled134134+ * by default in the future in 2.6.36) this will also mean both L1 and135135+ * L0s will be disabled when a pre 1.1 PCIe device is detected. We do136136+ * know L1 works correctly even for all ath5k pre 1.1 PCIe devices137137+ * though but cannot currently undue the effect of a blacklist, for138138+ * details you can read pcie_aspm_sanity_check() and see how it adjusts139139+ * the device link capability.140140+ *141141+ * It may be possible in the future to implement some PCI API to allow142142+ * drivers to override blacklists for pre 1.1 PCIe but for now it is143143+ * best to accept that both L0s and L1 will be disabled completely for144144+ * distributions shipping with CONFIG_PCIEASPM rather than having this145145+ * issue present. Motivation for adding this new API will be to help146146+ * with power consumption for some of these devices.147147+ */148148+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);149149+150150+ ret = pci_enable_device(pdev);151151+ if (ret) {152152+ dev_err(&pdev->dev, "can't enable device\n");153153+ goto err;154154+ }155155+156156+ /* XXX 32-bit addressing only */157157+ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));158158+ if (ret) {159159+ dev_err(&pdev->dev, "32-bit DMA not available\n");160160+ goto err_dis;161161+ }162162+163163+ /*164164+ * Cache line size is used to size and align various165165+ * structures used to communicate with the hardware.166166+ */167167+ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);168168+ if (csz == 0) {169169+ /*170170+ * Linux 2.4.18 (at least) writes the cache line size171171+ * register as a 16-bit wide register which is wrong.172172+ * We must have this setup properly for rx buffer173173+ * DMA to work so force a reasonable value here if it174174+ * comes up zero.175175+ */176176+ csz = L1_CACHE_BYTES >> 2;177177+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);178178+ }179179+ /*180180+ * The default setting of latency timer yields poor results,181181+ * set it to the value used by other systems. It may be worth182182+ * tweaking this setting more.183183+ */184184+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);185185+186186+ /* Enable bus mastering */187187+ pci_set_master(pdev);188188+189189+ /*190190+ * Disable the RETRY_TIMEOUT register (0x41) to keep191191+ * PCI Tx retries from interfering with C3 CPU state.192192+ */193193+ pci_write_config_byte(pdev, 0x41, 0);194194+195195+ ret = pci_request_region(pdev, 0, "ath5k");196196+ if (ret) {197197+ dev_err(&pdev->dev, "cannot reserve PCI memory region\n");198198+ goto err_dis;199199+ }200200+201201+ mem = pci_iomap(pdev, 0, 0);202202+ if (!mem) {203203+ dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;204204+ ret = -EIO;205205+ goto err_reg;206206+ }207207+208208+ /*209209+ * Allocate hw (mac80211 main struct)210210+ * and hw->priv (driver private data)211211+ */212212+ hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);213213+ if (hw == NULL) {214214+ dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");215215+ ret = -ENOMEM;216216+ goto err_map;217217+ }218218+219219+ dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));220220+221221+ sc = hw->priv;222222+ sc->hw = hw;223223+ sc->pdev = pdev;224224+ sc->dev = &pdev->dev;225225+ sc->irq = pdev->irq;226226+ sc->devid = id->device;227227+ sc->iobase = mem; /* So we can unmap it on detach */228228+229229+ /* Initialize */230230+ ret = ath5k_init_softc(sc, &ath_pci_bus_ops);231231+ if (ret)232232+ goto err_free;233233+234234+ /* Set private data */235235+ pci_set_drvdata(pdev, hw);236236+237237+ return 0;238238+err_free:239239+ ieee80211_free_hw(hw);240240+err_map:241241+ pci_iounmap(pdev, mem);242242+err_reg:243243+ pci_release_region(pdev, 0);244244+err_dis:245245+ pci_disable_device(pdev);246246+err:247247+ return ret;248248+}249249+250250+static void __devexit251251+ath5k_pci_remove(struct pci_dev *pdev)252252+{253253+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);254254+ struct ath5k_softc *sc = hw->priv;255255+256256+ ath5k_deinit_softc(sc);257257+ pci_iounmap(pdev, sc->iobase);258258+ pci_release_region(pdev, 0);259259+ pci_disable_device(pdev);260260+ ieee80211_free_hw(hw);261261+}262262+263263+#ifdef CONFIG_PM_SLEEP264264+static int ath5k_pci_suspend(struct device *dev)265265+{266266+ struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));267267+268268+ ath5k_led_off(sc);269269+ return 0;270270+}271271+272272+static int ath5k_pci_resume(struct device *dev)273273+{274274+ struct pci_dev *pdev = to_pci_dev(dev);275275+ struct ath5k_softc *sc = pci_get_drvdata(pdev);276276+277277+ /*278278+ * Suspend/Resume resets the PCI configuration space, so we have to279279+ * re-disable the RETRY_TIMEOUT register (0x41) to keep280280+ * PCI Tx retries from interfering with C3 CPU state281281+ */282282+ pci_write_config_byte(pdev, 0x41, 0);283283+284284+ ath5k_led_enable(sc);285285+ return 0;286286+}287287+288288+static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);289289+#define ATH5K_PM_OPS (&ath5k_pm_ops)290290+#else291291+#define ATH5K_PM_OPS NULL292292+#endif /* CONFIG_PM_SLEEP */293293+294294+static struct pci_driver ath5k_pci_driver = {295295+ .name = KBUILD_MODNAME,296296+ .id_table = ath5k_pci_id_table,297297+ .probe = ath5k_pci_probe,298298+ .remove = __devexit_p(ath5k_pci_remove),299299+ .driver.pm = ATH5K_PM_OPS,300300+};301301+302302+/*303303+ * Module init/exit functions304304+ */305305+static int __init306306+init_ath5k_pci(void)307307+{308308+ int ret;309309+310310+ ret = pci_register_driver(&ath5k_pci_driver);311311+ if (ret) {312312+ printk(KERN_ERR "ath5k_pci: can't register pci driver\n");313313+ return ret;314314+ }315315+316316+ return 0;317317+}318318+319319+static void __exit320320+exit_ath5k_pci(void)321321+{322322+ pci_unregister_driver(&ath5k_pci_driver);323323+}324324+325325+module_init(init_ath5k_pci);326326+module_exit(exit_ath5k_pci);
+388-205
drivers/net/wireless/ath/ath5k/pcu.c
···3131#include "debug.h"3232#include "base.h"33333434+/*3535+ * AR5212+ can use higher rates for ack transmition3636+ * based on current tx rate instead of the base rate.3737+ * It does this to better utilize channel usage.3838+ * This is a mapping between G rates (that cover both3939+ * CCK and OFDM) and ack rates that we use when setting4040+ * rate -> duration table. This mapping is hw-based so4141+ * don't change anything.4242+ *4343+ * To enable this functionality we must set4444+ * ah->ah_ack_bitrate_high to true else base rate is4545+ * used (1Mb for CCK, 6Mb for OFDM).4646+ */4747+static const unsigned int ack_rates_high[] =4848+/* Tx -> ACK */4949+/* 1Mb -> 1Mb */ { 0,5050+/* 2MB -> 2Mb */ 1,5151+/* 5.5Mb -> 2Mb */ 1,5252+/* 11Mb -> 2Mb */ 1,5353+/* 6Mb -> 6Mb */ 4,5454+/* 9Mb -> 6Mb */ 4,5555+/* 12Mb -> 12Mb */ 6,5656+/* 18Mb -> 12Mb */ 6,5757+/* 24Mb -> 24Mb */ 8,5858+/* 36Mb -> 24Mb */ 8,5959+/* 48Mb -> 24Mb */ 8,6060+/* 54Mb -> 24Mb */ 8 };6161+3462/*******************\3535-* Generic functions *6363+* Helper functions *3664\*******************/37653866/**3939- * ath5k_hw_set_opmode - Set PCU operating mode6767+ * ath5k_hw_get_frame_duration - Get tx time of a frame4068 *4169 * @ah: The &struct ath5k_hw4242- * @op_mode: &enum nl80211_iftype operating mode7070+ * @len: Frame's length in bytes7171+ * @rate: The @struct ieee80211_rate4372 *4444- * Initialize PCU for the various operating modes (AP/STA etc)7373+ * Calculate tx duration of a frame given it's rate and length7474+ * It extends ieee80211_generic_frame_duration for non standard7575+ * bwmodes.4576 */4646-int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)7777+int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,7878+ int len, struct ieee80211_rate *rate)4779{4848- struct ath_common *common = ath5k_hw_common(ah);4949- u32 pcu_reg, beacon_reg, low_id, high_id;8080+ struct ath5k_softc *sc = ah->ah_sc;8181+ int sifs, preamble, plcp_bits, sym_time;8282+ int bitrate, bits, symbols, symbol_bits;8383+ int dur;50845151- ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);5252-5353- /* Preserve rest settings */5454- pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;5555- pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP5656- | AR5K_STA_ID1_KEYSRCH_MODE5757- | (ah->ah_version == AR5K_AR5210 ?5858- (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));5959-6060- beacon_reg = 0;6161-6262- switch (op_mode) {6363- case NL80211_IFTYPE_ADHOC:6464- pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;6565- beacon_reg |= AR5K_BCR_ADHOC;6666- if (ah->ah_version == AR5K_AR5210)6767- pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;6868- else6969- AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);7070- break;7171-7272- case NL80211_IFTYPE_AP:7373- case NL80211_IFTYPE_MESH_POINT:7474- pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;7575- beacon_reg |= AR5K_BCR_AP;7676- if (ah->ah_version == AR5K_AR5210)7777- pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;7878- else7979- AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);8080- break;8181-8282- case NL80211_IFTYPE_STATION:8383- pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE8484- | (ah->ah_version == AR5K_AR5210 ?8585- AR5K_STA_ID1_PWR_SV : 0);8686- case NL80211_IFTYPE_MONITOR:8787- pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE8888- | (ah->ah_version == AR5K_AR5210 ?8989- AR5K_STA_ID1_NO_PSPOLL : 0);9090- break;9191-9292- default:9393- return -EINVAL;8585+ /* Fallback */8686+ if (!ah->ah_bwmode) {8787+ dur = ieee80211_generic_frame_duration(sc->hw,8888+ NULL, len, rate);8989+ return dur;9490 }95919696- /*9797- * Set PCU registers9898- */9999- low_id = get_unaligned_le32(common->macaddr);100100- high_id = get_unaligned_le16(common->macaddr + 4);101101- ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);102102- ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);9292+ bitrate = rate->bitrate;9393+ preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;9494+ plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;9595+ sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;10396104104- /*105105- * Set Beacon Control Register on 5210106106- */107107- if (ah->ah_version == AR5K_AR5210)108108- ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);9797+ switch (ah->ah_bwmode) {9898+ case AR5K_BWMODE_40MHZ:9999+ sifs = AR5K_INIT_SIFS_TURBO;100100+ preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;101101+ break;102102+ case AR5K_BWMODE_10MHZ:103103+ sifs = AR5K_INIT_SIFS_HALF_RATE;104104+ preamble *= 2;105105+ sym_time *= 2;106106+ break;107107+ case AR5K_BWMODE_5MHZ:108108+ sifs = AR5K_INIT_SIFS_QUARTER_RATE;109109+ preamble *= 4;110110+ sym_time *= 4;111111+ break;112112+ default:113113+ sifs = AR5K_INIT_SIFS_DEFAULT_BG;114114+ break;115115+ }109116110110- return 0;117117+ bits = plcp_bits + (len << 3);118118+ /* Bit rate is in 100Kbits */119119+ symbol_bits = bitrate * sym_time;120120+ symbols = DIV_ROUND_UP(bits * 10, symbol_bits);121121+122122+ dur = sifs + preamble + (sym_time * symbols);123123+124124+ return dur;111125}112126113127/**114114- * ath5k_hw_update - Update MIB counters (mac layer statistics)128128+ * ath5k_hw_get_default_slottime - Get the default slot time for current mode129129+ *130130+ * @ah: The &struct ath5k_hw131131+ */132132+unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)133133+{134134+ struct ieee80211_channel *channel = ah->ah_current_channel;135135+ unsigned int slot_time;136136+137137+ switch (ah->ah_bwmode) {138138+ case AR5K_BWMODE_40MHZ:139139+ slot_time = AR5K_INIT_SLOT_TIME_TURBO;140140+ break;141141+ case AR5K_BWMODE_10MHZ:142142+ slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;143143+ break;144144+ case AR5K_BWMODE_5MHZ:145145+ slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;146146+ break;147147+ case AR5K_BWMODE_DEFAULT:148148+ slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;149149+ default:150150+ if (channel->hw_value & CHANNEL_CCK)151151+ slot_time = AR5K_INIT_SLOT_TIME_B;152152+ break;153153+ }154154+155155+ return slot_time;156156+}157157+158158+/**159159+ * ath5k_hw_get_default_sifs - Get the default SIFS for current mode160160+ *161161+ * @ah: The &struct ath5k_hw162162+ */163163+unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)164164+{165165+ struct ieee80211_channel *channel = ah->ah_current_channel;166166+ unsigned int sifs;167167+168168+ switch (ah->ah_bwmode) {169169+ case AR5K_BWMODE_40MHZ:170170+ sifs = AR5K_INIT_SIFS_TURBO;171171+ break;172172+ case AR5K_BWMODE_10MHZ:173173+ sifs = AR5K_INIT_SIFS_HALF_RATE;174174+ break;175175+ case AR5K_BWMODE_5MHZ:176176+ sifs = AR5K_INIT_SIFS_QUARTER_RATE;177177+ break;178178+ case AR5K_BWMODE_DEFAULT:179179+ sifs = AR5K_INIT_SIFS_DEFAULT_BG;180180+ default:181181+ if (channel->hw_value & CHANNEL_5GHZ)182182+ sifs = AR5K_INIT_SIFS_DEFAULT_A;183183+ break;184184+ }185185+186186+ return sifs;187187+}188188+189189+/**190190+ * ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics)115191 *116192 * @ah: The &struct ath5k_hw117193 *···209133 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);210134}211135212212-/**213213- * ath5k_hw_set_ack_bitrate - set bitrate for ACKs214214- *215215- * @ah: The &struct ath5k_hw216216- * @high: Flag to determine if we want to use high transmission rate217217- * for ACKs or not218218- *219219- * If high flag is set, we tell hw to use a set of control rates based on220220- * the current transmission rate (check out control_rates array inside reset.c).221221- * If not hw just uses the lowest rate available for the current modulation222222- * scheme being used (1Mbit for CCK and 6Mbits for OFDM).223223- */224224-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)225225-{226226- if (ah->ah_version != AR5K_AR5212)227227- return;228228- else {229229- u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;230230- if (high)231231- AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);232232- else233233- AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);234234- }235235-}236236-237136238137/******************\239138* ACK/CTS Timeouts *240139\******************/140140+141141+/**142142+ * ath5k_hw_write_rate_duration - fill rate code to duration table143143+ *144144+ * @ah: the &struct ath5k_hw145145+ * @mode: one of enum ath5k_driver_mode146146+ *147147+ * Write the rate code to duration table upon hw reset. This is a helper for148148+ * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on149149+ * the hardware, based on current mode, for each rate. The rates which are150150+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have151151+ * different rate code so we write their value twice (one for long preamble152152+ * and one for short).153153+ *154154+ * Note: Band doesn't matter here, if we set the values for OFDM it works155155+ * on both a and g modes. So all we have to do is set values for all g rates156156+ * that include all OFDM and CCK rates.157157+ *158158+ */159159+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah)160160+{161161+ struct ath5k_softc *sc = ah->ah_sc;162162+ struct ieee80211_rate *rate;163163+ unsigned int i;164164+ /* 802.11g covers both OFDM and CCK */165165+ u8 band = IEEE80211_BAND_2GHZ;166166+167167+ /* Write rate duration table */168168+ for (i = 0; i < sc->sbands[band].n_bitrates; i++) {169169+ u32 reg;170170+ u16 tx_time;171171+172172+ if (ah->ah_ack_bitrate_high)173173+ rate = &sc->sbands[band].bitrates[ack_rates_high[i]];174174+ /* CCK -> 1Mb */175175+ else if (i < 4)176176+ rate = &sc->sbands[band].bitrates[0];177177+ /* OFDM -> 6Mb */178178+ else179179+ rate = &sc->sbands[band].bitrates[4];180180+181181+ /* Set ACK timeout */182182+ reg = AR5K_RATE_DUR(rate->hw_value);183183+184184+ /* An ACK frame consists of 10 bytes. If you add the FCS,185185+ * which ieee80211_generic_frame_duration() adds,186186+ * its 14 bytes. Note we use the control rate and not the187187+ * actual rate for this rate. See mac80211 tx.c188188+ * ieee80211_duration() for a brief description of189189+ * what rate we should choose to TX ACKs. */190190+ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);191191+192192+ tx_time = le16_to_cpu(tx_time);193193+194194+ ath5k_hw_reg_write(ah, tx_time, reg);195195+196196+ if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))197197+ continue;198198+199199+ /*200200+ * We're not distinguishing short preamble here,201201+ * This is true, all we'll get is a longer value here202202+ * which is not necessarilly bad. We could use203203+ * export ieee80211_frame_duration() but that needs to be204204+ * fixed first to be properly used by mac802111 drivers:205205+ *206206+ * - remove erp stuff and let the routine figure ofdm207207+ * erp rates208208+ * - remove passing argument ieee80211_local as209209+ * drivers don't have access to it210210+ * - move drivers using ieee80211_generic_frame_duration()211211+ * to this212212+ */213213+ ath5k_hw_reg_write(ah, tx_time,214214+ reg + (AR5K_SET_SHORT_PREAMBLE << 2));215215+ }216216+}241217242218/**243219 * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU···327199 return 0;328200}329201330330-/**331331- * ath5k_hw_htoclock - Translate usec to hw clock units332332- *333333- * @ah: The &struct ath5k_hw334334- * @usec: value in microseconds335335- */336336-unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)337337-{338338- struct ath_common *common = ath5k_hw_common(ah);339339- return usec * common->clockrate;340340-}341202342342-/**343343- * ath5k_hw_clocktoh - Translate hw clock units to usec344344- * @clock: value in hw clock units345345- */346346-unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)347347-{348348- struct ath_common *common = ath5k_hw_common(ah);349349- return clock / common->clockrate;350350-}351351-352352-/**353353- * ath5k_hw_set_clockrate - Set common->clockrate for the current channel354354- *355355- * @ah: The &struct ath5k_hw356356- */357357-void ath5k_hw_set_clockrate(struct ath5k_hw *ah)358358-{359359- struct ieee80211_channel *channel = ah->ah_current_channel;360360- struct ath_common *common = ath5k_hw_common(ah);361361- int clock;362362-363363- if (channel->hw_value & CHANNEL_5GHZ)364364- clock = 40; /* 802.11a */365365- else if (channel->hw_value & CHANNEL_CCK)366366- clock = 22; /* 802.11b */367367- else368368- clock = 44; /* 802.11g */369369-370370- /* Clock rate in turbo modes is twice the normal rate */371371- if (channel->hw_value & CHANNEL_TURBO)372372- clock *= 2;373373-374374- common->clockrate = clock;375375-}376376-377377-/**378378- * ath5k_hw_get_default_slottime - Get the default slot time for current mode379379- *380380- * @ah: The &struct ath5k_hw381381- */382382-static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)383383-{384384- struct ieee80211_channel *channel = ah->ah_current_channel;385385-386386- if (channel->hw_value & CHANNEL_TURBO)387387- return 6; /* both turbo modes */388388-389389- if (channel->hw_value & CHANNEL_CCK)390390- return 20; /* 802.11b */391391-392392- return 9; /* 802.11 a/g */393393-}394394-395395-/**396396- * ath5k_hw_get_default_sifs - Get the default SIFS for current mode397397- *398398- * @ah: The &struct ath5k_hw399399- */400400-static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)401401-{402402- struct ieee80211_channel *channel = ah->ah_current_channel;403403-404404- if (channel->hw_value & CHANNEL_TURBO)405405- return 8; /* both turbo modes */406406-407407- if (channel->hw_value & CHANNEL_5GHZ)408408- return 16; /* 802.11a */409409-410410- return 10; /* 802.11 b/g */411411-}203203+/*******************\204204+* RX filter Control *205205+\*******************/412206413207/**414208 * ath5k_hw_set_lladdr - Set station id···410360 memcpy(common->bssidmask, mask, ETH_ALEN);411361 if (ah->ah_version == AR5K_AR5212)412362 ath_hw_setbssidmask(common);413413-}414414-415415-/************\416416-* RX Control *417417-\************/418418-419419-/**420420- * ath5k_hw_start_rx_pcu - Start RX engine421421- *422422- * @ah: The &struct ath5k_hw423423- *424424- * Starts RX engine on PCU so that hw can process RXed frames425425- * (ACK etc).426426- *427427- * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma428428- */429429-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)430430-{431431- AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);432432-}433433-434434-/**435435- * at5k_hw_stop_rx_pcu - Stop RX engine436436- *437437- * @ah: The &struct ath5k_hw438438- *439439- * Stops RX engine on PCU440440- *441441- * TODO: Detach ANI here442442- */443443-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)444444-{445445- AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);446363}447364448365/*···763746 * @ah: The &struct ath5k_hw764747 * @coverage_class: IEEE 802.11 coverage class number765748 *766766- * Sets slot time, ACK timeout and CTS timeout for given coverage class.749749+ * Sets IFS intervals and ACK/CTS timeouts for given coverage class.767750 */768751void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)769752{···772755 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;773756 int cts_timeout = ack_timeout;774757775775- ath5k_hw_set_slot_time(ah, slot_time);758758+ ath5k_hw_set_ifs_intervals(ah, slot_time);776759 ath5k_hw_set_ack_timeout(ah, ack_timeout);777760 ath5k_hw_set_cts_timeout(ah, cts_timeout);778761779762 ah->ah_coverage_class = coverage_class;763763+}764764+765765+/***************************\766766+* Init/Start/Stop functions *767767+\***************************/768768+769769+/**770770+ * ath5k_hw_start_rx_pcu - Start RX engine771771+ *772772+ * @ah: The &struct ath5k_hw773773+ *774774+ * Starts RX engine on PCU so that hw can process RXed frames775775+ * (ACK etc).776776+ *777777+ * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma778778+ */779779+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)780780+{781781+ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);782782+}783783+784784+/**785785+ * at5k_hw_stop_rx_pcu - Stop RX engine786786+ *787787+ * @ah: The &struct ath5k_hw788788+ *789789+ * Stops RX engine on PCU790790+ */791791+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)792792+{793793+ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);794794+}795795+796796+/**797797+ * ath5k_hw_set_opmode - Set PCU operating mode798798+ *799799+ * @ah: The &struct ath5k_hw800800+ * @op_mode: &enum nl80211_iftype operating mode801801+ *802802+ * Configure PCU for the various operating modes (AP/STA etc)803803+ */804804+int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)805805+{806806+ struct ath_common *common = ath5k_hw_common(ah);807807+ u32 pcu_reg, beacon_reg, low_id, high_id;808808+809809+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);810810+811811+ /* Preserve rest settings */812812+ pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;813813+ pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP814814+ | AR5K_STA_ID1_KEYSRCH_MODE815815+ | (ah->ah_version == AR5K_AR5210 ?816816+ (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));817817+818818+ beacon_reg = 0;819819+820820+ switch (op_mode) {821821+ case NL80211_IFTYPE_ADHOC:822822+ pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;823823+ beacon_reg |= AR5K_BCR_ADHOC;824824+ if (ah->ah_version == AR5K_AR5210)825825+ pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;826826+ else827827+ AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);828828+ break;829829+830830+ case NL80211_IFTYPE_AP:831831+ case NL80211_IFTYPE_MESH_POINT:832832+ pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;833833+ beacon_reg |= AR5K_BCR_AP;834834+ if (ah->ah_version == AR5K_AR5210)835835+ pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;836836+ else837837+ AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);838838+ break;839839+840840+ case NL80211_IFTYPE_STATION:841841+ pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE842842+ | (ah->ah_version == AR5K_AR5210 ?843843+ AR5K_STA_ID1_PWR_SV : 0);844844+ case NL80211_IFTYPE_MONITOR:845845+ pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE846846+ | (ah->ah_version == AR5K_AR5210 ?847847+ AR5K_STA_ID1_NO_PSPOLL : 0);848848+ break;849849+850850+ default:851851+ return -EINVAL;852852+ }853853+854854+ /*855855+ * Set PCU registers856856+ */857857+ low_id = get_unaligned_le32(common->macaddr);858858+ high_id = get_unaligned_le16(common->macaddr + 4);859859+ ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);860860+ ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);861861+862862+ /*863863+ * Set Beacon Control Register on 5210864864+ */865865+ if (ah->ah_version == AR5K_AR5210)866866+ ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);867867+868868+ return 0;869869+}870870+871871+void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,872872+ u8 mode)873873+{874874+ /* Set bssid and bssid mask */875875+ ath5k_hw_set_bssid(ah);876876+877877+ /* Set PCU config */878878+ ath5k_hw_set_opmode(ah, op_mode);879879+880880+ /* Write rate duration table only on AR5212 and if881881+ * virtual interface has already been brought up882882+ * XXX: rethink this after new mode changes to883883+ * mac80211 are integrated */884884+ if (ah->ah_version == AR5K_AR5212 &&885885+ ah->ah_sc->nvifs)886886+ ath5k_hw_write_rate_duration(ah);887887+888888+ /* Set RSSI/BRSSI thresholds889889+ *890890+ * Note: If we decide to set this value891891+ * dynamicaly, have in mind that when AR5K_RSSI_THR892892+ * register is read it might return 0x40 if we haven't893893+ * wrote anything to it plus BMISS RSSI threshold is zeroed.894894+ * So doing a save/restore procedure here isn't the right895895+ * choice. Instead store it on ath5k_hw */896896+ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |897897+ AR5K_TUNE_BMISS_THRES <<898898+ AR5K_RSSI_THR_BMISS_S),899899+ AR5K_RSSI_THR);900900+901901+ /* MIC QoS support */902902+ if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {903903+ ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);904904+ ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);905905+ }906906+907907+ /* QoS NOACK Policy */908908+ if (ah->ah_version == AR5K_AR5212) {909909+ ath5k_hw_reg_write(ah,910910+ AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |911911+ AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |912912+ AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),913913+ AR5K_QOS_NOACK);914914+ }915915+916916+ /* Restore slot time and ACK timeouts */917917+ if (ah->ah_coverage_class > 0)918918+ ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);919919+920920+ /* Set ACK bitrate mode (see ack_rates_high) */921921+ if (ah->ah_version == AR5K_AR5212) {922922+ u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;923923+ if (ah->ah_ack_bitrate_high)924924+ AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);925925+ else926926+ AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);927927+ }928928+ return;780929}
+494-147
drivers/net/wireless/ath/ath5k/phy.c
···2929#include "rfbuffer.h"3030#include "rfgain.h"31313232+3333+/******************\3434+* Helper functions *3535+\******************/3636+3737+/*3838+ * Get the PHY Chip revision3939+ */4040+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)4141+{4242+ unsigned int i;4343+ u32 srev;4444+ u16 ret;4545+4646+ /*4747+ * Set the radio chip access register4848+ */4949+ switch (chan) {5050+ case CHANNEL_2GHZ:5151+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));5252+ break;5353+ case CHANNEL_5GHZ:5454+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));5555+ break;5656+ default:5757+ return 0;5858+ }5959+6060+ mdelay(2);6161+6262+ /* ...wait until PHY is ready and read the selected radio revision */6363+ ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));6464+6565+ for (i = 0; i < 8; i++)6666+ ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));6767+6868+ if (ah->ah_version == AR5K_AR5210) {6969+ srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;7070+ ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;7171+ } else {7272+ srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;7373+ ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |7474+ ((srev & 0x0f) << 4), 8);7575+ }7676+7777+ /* Reset to the 5GHz mode */7878+ ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));7979+8080+ return ret;8181+}8282+8383+/*8484+ * Check if a channel is supported8585+ */8686+bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)8787+{8888+ /* Check if the channel is in our supported range */8989+ if (flags & CHANNEL_2GHZ) {9090+ if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&9191+ (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))9292+ return true;9393+ } else if (flags & CHANNEL_5GHZ)9494+ if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&9595+ (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))9696+ return true;9797+9898+ return false;9999+}100100+101101+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,102102+ struct ieee80211_channel *channel)103103+{104104+ u8 refclk_freq;105105+106106+ if ((ah->ah_radio == AR5K_RF5112) ||107107+ (ah->ah_radio == AR5K_RF5413) ||108108+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))109109+ refclk_freq = 40;110110+ else111111+ refclk_freq = 32;112112+113113+ if ((channel->center_freq % refclk_freq != 0) &&114114+ ((channel->center_freq % refclk_freq < 10) ||115115+ (channel->center_freq % refclk_freq > 22)))116116+ return true;117117+ else118118+ return false;119119+}120120+32121/*33122 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER34123 */···198109199110 return data;200111}112112+113113+/**114114+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212115115+ *116116+ * @ah: the &struct ath5k_hw117117+ * @channel: the currently set channel upon reset118118+ *119119+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM120120+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_phy_init.121121+ *122122+ * Since delta slope is floating point we split it on its exponent and123123+ * mantissa and provide these values on hw.124124+ *125125+ * For more infos i think this patent is related126126+ * http://www.freepatentsonline.com/7184495.html127127+ */128128+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,129129+ struct ieee80211_channel *channel)130130+{131131+ /* Get exponent and mantissa and set it */132132+ u32 coef_scaled, coef_exp, coef_man,133133+ ds_coef_exp, ds_coef_man, clock;134134+135135+ BUG_ON(!(ah->ah_version == AR5K_AR5212) ||136136+ !(channel->hw_value & CHANNEL_OFDM));137137+138138+ /* Get coefficient139139+ * ALGO: coef = (5 * clock / carrier_freq) / 2140140+ * we scale coef by shifting clock value by 24 for141141+ * better precision since we use integers */142142+ switch (ah->ah_bwmode) {143143+ case AR5K_BWMODE_40MHZ:144144+ clock = 40 * 2;145145+ break;146146+ case AR5K_BWMODE_10MHZ:147147+ clock = 40 / 2;148148+ break;149149+ case AR5K_BWMODE_5MHZ:150150+ clock = 40 / 4;151151+ break;152152+ default:153153+ clock = 40;154154+ break;155155+ }156156+ coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;157157+158158+ /* Get exponent159159+ * ALGO: coef_exp = 14 - highest set bit position */160160+ coef_exp = ilog2(coef_scaled);161161+162162+ /* Doesn't make sense if it's zero*/163163+ if (!coef_scaled || !coef_exp)164164+ return -EINVAL;165165+166166+ /* Note: we've shifted coef_scaled by 24 */167167+ coef_exp = 14 - (coef_exp - 24);168168+169169+170170+ /* Get mantissa (significant digits)171171+ * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */172172+ coef_man = coef_scaled +173173+ (1 << (24 - coef_exp - 1));174174+175175+ /* Calculate delta slope coefficient exponent176176+ * and mantissa (remove scaling) and set them on hw */177177+ ds_coef_man = coef_man >> (24 - coef_exp);178178+ ds_coef_exp = coef_exp - 16;179179+180180+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,181181+ AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);182182+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,183183+ AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);184184+185185+ return 0;186186+}187187+188188+int ath5k_hw_phy_disable(struct ath5k_hw *ah)189189+{190190+ /*Just a try M.F.*/191191+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);192192+193193+ return 0;194194+}195195+201196202197/**********************\203198* RF Gain optimization *···609436/* Write initial RF gain table to set the RF sensitivity610437 * this one works on all RF chips and has nothing to do611438 * with gain_F calibration */612612-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)439439+static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)613440{614441 const struct ath5k_ini_rfgain *ath5k_rfg;615442 unsigned int i, size;···667494* RF Registers setup *668495\********************/669496670670-671497/*672498 * Setup RF registers by writing RF buffer on hw673499 */674674-int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,675675- unsigned int mode)500500+static int ath5k_hw_rfregs_init(struct ath5k_hw *ah,501501+ struct ieee80211_channel *channel, unsigned int mode)676502{677503 const struct ath5k_rf_reg *rf_regs;678504 const struct ath5k_ini_rfbuffer *ini_rfb;···824652825653 g_step = &go->go_step[ah->ah_gain.g_step_idx];826654655655+ /* Set turbo mode (N/A on RF5413) */656656+ if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&657657+ (ah->ah_radio != AR5K_RF5413))658658+ ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_TURBO, false);659659+827660 /* Bank Modifications (chip-specific) */828661 if (ah->ah_radio == AR5K_RF5111) {829662···868691 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],869692 AR5K_RF_PLO_SEL, true);870693871871- /* TODO: Half/quarter channel support */694694+ /* Tweak power detectors for half/quarter rate support */695695+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||696696+ ah->ah_bwmode == AR5K_BWMODE_10MHZ) {697697+ u8 wait_i;698698+699699+ ath5k_hw_rfb_op(ah, rf_regs, 0x1f,700700+ AR5K_RF_WAIT_S, true);701701+702702+ wait_i = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?703703+ 0x1f : 0x10;704704+705705+ ath5k_hw_rfb_op(ah, rf_regs, wait_i,706706+ AR5K_RF_WAIT_I, true);707707+ ath5k_hw_rfb_op(ah, rf_regs, 3,708708+ AR5K_RF_MAX_TIME, true);709709+710710+ }872711 }873712874713 if (ah->ah_radio == AR5K_RF5112) {···982789 ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],983790 AR5K_RF_GAIN_I, true);984791985985- /* TODO: Half/quarter channel support */792792+ /* Tweak power detector for half/quarter rates */793793+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ ||794794+ ah->ah_bwmode == AR5K_BWMODE_10MHZ) {795795+ u8 pd_delay;986796797797+ pd_delay = (ah->ah_bwmode == AR5K_BWMODE_5MHZ) ?798798+ 0xf : 0x8;799799+800800+ ath5k_hw_rfb_op(ah, rf_regs, pd_delay,801801+ AR5K_RF_PD_PERIOD_A, true);802802+ ath5k_hw_rfb_op(ah, rf_regs, 0xf,803803+ AR5K_RF_PD_DELAY_A, true);804804+805805+ }987806 }988807989808 if (ah->ah_radio == AR5K_RF5413 &&···1025820/**************************\1026821 PHY/RF channel functions1027822\**************************/10281028-10291029-/*10301030- * Check if a channel is supported10311031- */10321032-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)10331033-{10341034- /* Check if the channel is in our supported range */10351035- if (flags & CHANNEL_2GHZ) {10361036- if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&10371037- (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))10381038- return true;10391039- } else if (flags & CHANNEL_5GHZ)10401040- if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&10411041- (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))10421042- return true;10431043-10441044- return false;10451045-}10468231047824/*1048825 * Convertion needed for RF5110···12321045/*12331046 * Set a channel on the radio chip12341047 */12351235-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)10481048+static int ath5k_hw_channel(struct ath5k_hw *ah,10491049+ struct ieee80211_channel *channel)12361050{12371051 int ret;12381052 /*···12801092 }1281109312821094 ah->ah_current_channel = channel;12831283- ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;12841284- ath5k_hw_set_clockrate(ah);1285109512861096 return 0;12871097}···1363117713641178 switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {13651179 case CHANNEL_A:13661366- case CHANNEL_T:13671180 case CHANNEL_XR:13681181 ee_mode = AR5K_EEPROM_MODE_11A;13691182 break;13701183 case CHANNEL_G:13711371- case CHANNEL_TG:13721184 ee_mode = AR5K_EEPROM_MODE_11G;13731185 break;13741186 default:···16031419 return ret;16041420}1605142114221422+16061423/***************************\16071424* Spur mitigation functions *16081425\***************************/1609142616101610-bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,16111611- struct ieee80211_channel *channel)16121612-{16131613- u8 refclk_freq;16141614-16151615- if ((ah->ah_radio == AR5K_RF5112) ||16161616- (ah->ah_radio == AR5K_RF5413) ||16171617- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))16181618- refclk_freq = 40;16191619- else16201620- refclk_freq = 32;16211621-16221622- if ((channel->center_freq % refclk_freq != 0) &&16231623- ((channel->center_freq % refclk_freq < 10) ||16241624- (channel->center_freq % refclk_freq > 22)))16251625- return true;16261626- else16271627- return false;16281628-}16291629-16301630-void14271427+static void16311428ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,16321429 struct ieee80211_channel *channel)16331430{···16371472 spur_chan_fbin = AR5K_EEPROM_NO_SPUR;16381473 spur_detection_window = AR5K_SPUR_CHAN_WIDTH;16391474 /* XXX: Half/Quarter channels ?*/16401640- if (channel->hw_value & CHANNEL_TURBO)14751475+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)16411476 spur_detection_window *= 2;1642147716431478 for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {···16661501 * Calculate deltas:16671502 * spur_freq_sigma_delta -> spur_offset / sample_freq << 2116681503 * spur_delta_phase -> spur_offset / chip_freq << 1116691669- * Note: Both values have 100KHz resolution15041504+ * Note: Both values have 100Hz resolution16701505 */16711671- /* XXX: Half/Quarter rate channels ? */16721672- switch (channel->hw_value) {16731673- case CHANNEL_A:16741674- /* Both sample_freq and chip_freq are 40MHz */16751675- spur_delta_phase = (spur_offset << 17) / 25;16761676- spur_freq_sigma_delta = (spur_delta_phase >> 10);16771677- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;16781678- break;16791679- case CHANNEL_G:16801680- /* sample_freq -> 40MHz chip_freq -> 44MHz16811681- * (for b compatibility) */16821682- spur_freq_sigma_delta = (spur_offset << 8) / 55;16831683- spur_delta_phase = (spur_offset << 17) / 25;16841684- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;16851685- break;16861686- case CHANNEL_T:16871687- case CHANNEL_TG:15061506+ switch (ah->ah_bwmode) {15071507+ case AR5K_BWMODE_40MHZ:16881508 /* Both sample_freq and chip_freq are 80MHz */16891509 spur_delta_phase = (spur_offset << 16) / 25;16901510 spur_freq_sigma_delta = (spur_delta_phase >> 10);16911691- symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;15111511+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz * 2;16921512 break;15131513+ case AR5K_BWMODE_10MHZ:15141514+ /* Both sample_freq and chip_freq are 20MHz (?) */15151515+ spur_delta_phase = (spur_offset << 18) / 25;15161516+ spur_freq_sigma_delta = (spur_delta_phase >> 10);15171517+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2;15181518+ case AR5K_BWMODE_5MHZ:15191519+ /* Both sample_freq and chip_freq are 10MHz (?) */15201520+ spur_delta_phase = (spur_offset << 19) / 25;15211521+ spur_freq_sigma_delta = (spur_delta_phase >> 10);15221522+ symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4;16931523 default:16941694- return;15241524+ if (channel->hw_value == CHANNEL_A) {15251525+ /* Both sample_freq and chip_freq are 40MHz */15261526+ spur_delta_phase = (spur_offset << 17) / 25;15271527+ spur_freq_sigma_delta =15281528+ (spur_delta_phase >> 10);15291529+ symbol_width =15301530+ AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;15311531+ } else {15321532+ /* sample_freq -> 40MHz chip_freq -> 44MHz15331533+ * (for b compatibility) */15341534+ spur_delta_phase = (spur_offset << 17) / 25;15351535+ spur_freq_sigma_delta =15361536+ (spur_offset << 8) / 55;15371537+ symbol_width =15381538+ AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;15391539+ }15401540+ break;16951541 }1696154216971543 /* Calculate pilot and magnitude masks */···18421666 }18431667}1844166818451845-/********************\18461846- Misc PHY functions18471847-\********************/18481848-18491849-int ath5k_hw_phy_disable(struct ath5k_hw *ah)18501850-{18511851- /*Just a try M.F.*/18521852- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);18531853-18541854- return 0;18551855-}18561856-18571857-/*18581858- * Get the PHY Chip revision18591859- */18601860-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)18611861-{18621862- unsigned int i;18631863- u32 srev;18641864- u16 ret;18651865-18661866- /*18671867- * Set the radio chip access register18681868- */18691869- switch (chan) {18701870- case CHANNEL_2GHZ:18711871- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));18721872- break;18731873- case CHANNEL_5GHZ:18741874- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));18751875- break;18761876- default:18771877- return 0;18781878- }18791879-18801880- mdelay(2);18811881-18821882- /* ...wait until PHY is ready and read the selected radio revision */18831883- ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));18841884-18851885- for (i = 0; i < 8; i++)18861886- ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));18871887-18881888- if (ah->ah_version == AR5K_AR5210) {18891889- srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;18901890- ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;18911891- } else {18921892- srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;18931893- ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |18941894- ((srev & 0x0f) << 4), 8);18951895- }18961896-18971897- /* Reset to the 5GHz mode */18981898- ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));18991899-19001900- return ret;19011901-}1902166919031670/*****************\19041671* Antenna control *···1949183019501831 switch (channel->hw_value & CHANNEL_MODES) {19511832 case CHANNEL_A:19521952- case CHANNEL_T:19531833 case CHANNEL_XR:19541834 ee_mode = AR5K_EEPROM_MODE_11A;19551835 break;19561836 case CHANNEL_G:19571957- case CHANNEL_TG:19581837 ee_mode = AR5K_EEPROM_MODE_11G;19591838 break;19601839 case CHANNEL_B:···2386226923872270 switch (channel->hw_value & CHANNEL_MODES) {23882271 case CHANNEL_A:23892389- ctl_mode |= AR5K_CTL_11A;22722272+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)22732273+ ctl_mode |= AR5K_CTL_TURBO;22742274+ else22752275+ ctl_mode |= AR5K_CTL_11A;23902276 break;23912277 case CHANNEL_G:23922392- ctl_mode |= AR5K_CTL_11G;22782278+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)22792279+ ctl_mode |= AR5K_CTL_TURBOG;22802280+ else22812281+ ctl_mode |= AR5K_CTL_11G;23932282 break;23942283 case CHANNEL_B:23952284 ctl_mode |= AR5K_CTL_11B;23962396- break;23972397- case CHANNEL_T:23982398- ctl_mode |= AR5K_CTL_TURBO;23992399- break;24002400- case CHANNEL_TG:24012401- ctl_mode |= AR5K_CTL_TURBOG;24022285 break;24032286 case CHANNEL_XR:24042287 /* Fall through */···31012984/*31022985 * Set transmission power31032986 */31043104-int29872987+static int31052988ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,31063106- u8 ee_mode, u8 txpower)29892989+ u8 ee_mode, u8 txpower, bool fast)31072990{31082991 struct ath5k_rate_pcal_info rate_info;31092992 u8 type;···3122300531233006 /* Initialize TX power table */31243007 switch (ah->ah_radio) {30083008+ case AR5K_RF5110:30093009+ /* TODO */30103010+ return 0;31253011 case AR5K_RF5111:31263012 type = AR5K_PWRTABLE_PWR_TO_PCDAC;31273013 break;···31423022 return -EINVAL;31433023 }3144302431453145- /* FIXME: Only on channel/mode change */31463146- ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);31473147- if (ret)31483148- return ret;30253025+ /* If fast is set it means we are on the same channel/mode30263026+ * so there is no need to recalculate the powertable, we 'll30273027+ * just use the cached one */30283028+ if (!fast) {30293029+ ret = ath5k_setup_channel_powertable(ah, channel,30303030+ ee_mode, type);30313031+ if (ret)30323032+ return ret;30333033+ }3149303431503035 /* Limit max power if we have a CTL available */31513036 ath5k_get_max_ctl_power(ah, channel);···3211308632123087 switch (channel->hw_value & CHANNEL_MODES) {32133088 case CHANNEL_A:32143214- case CHANNEL_T:32153089 case CHANNEL_XR:32163090 ee_mode = AR5K_EEPROM_MODE_11A;32173091 break;32183092 case CHANNEL_G:32193219- case CHANNEL_TG:32203093 ee_mode = AR5K_EEPROM_MODE_11G;32213094 break;32223095 case CHANNEL_B:···32293106 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,32303107 "changing txpower to %d\n", txpower);3231310832323232- return ath5k_hw_txpower(ah, channel, ee_mode, txpower);31093109+ return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true);31103110+}31113111+31123112+/*************\31133113+ Init function31143114+\*************/31153115+31163116+int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,31173117+ u8 mode, u8 ee_mode, u8 freq, bool fast)31183118+{31193119+ struct ieee80211_channel *curr_channel;31203120+ int ret, i;31213121+ u32 phy_tst1;31223122+ bool fast_txp;31233123+ ret = 0;31243124+31253125+ /*31263126+ * Sanity check for fast flag31273127+ * Don't try fast channel change when changing modulation31283128+ * mode/band. We check for chip compatibility on31293129+ * ath5k_hw_reset.31303130+ */31313131+ curr_channel = ah->ah_current_channel;31323132+ if (fast && (channel->hw_value != curr_channel->hw_value))31333133+ return -EINVAL;31343134+31353135+ /*31363136+ * On fast channel change we only set the synth parameters31373137+ * while PHY is running, enable calibration and skip the rest.31383138+ */31393139+ if (fast) {31403140+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,31413141+ AR5K_PHY_RFBUS_REQ_REQUEST);31423142+ for (i = 0; i < 100; i++) {31433143+ if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))31443144+ break;31453145+ udelay(5);31463146+ }31473147+ /* Failed */31483148+ if (i >= 100)31493149+ return -EIO;31503150+ }31513151+31523152+ /*31533153+ * If we don't change channel/mode skip31543154+ * tx powertable calculation and use the31553155+ * cached one.31563156+ */31573157+ if ((channel->hw_value == curr_channel->hw_value) &&31583158+ (channel->center_freq == curr_channel->center_freq))31593159+ fast_txp = true;31603160+ else31613161+ fast_txp = false;31623162+31633163+ /*31643164+ * Set TX power31653165+ *31663166+ * Note: We need to do that before we set31673167+ * RF buffer settings on 5211/5212+ so that we31683168+ * properly set curve indices.31693169+ */31703170+ ret = ath5k_hw_txpower(ah, channel, ee_mode,31713171+ ah->ah_txpower.txp_max_pwr / 2,31723172+ fast_txp);31733173+ if (ret)31743174+ return ret;31753175+31763176+ /*31773177+ * For 5210 we do all initialization using31783178+ * initvals, so we don't have to modify31793179+ * any settings (5210 also only supports31803180+ * a/aturbo modes)31813181+ */31823182+ if ((ah->ah_version != AR5K_AR5210) && !fast) {31833183+31843184+ /*31853185+ * Write initial RF gain settings31863186+ * This should work for both 5111/511231873187+ */31883188+ ret = ath5k_hw_rfgain_init(ah, freq);31893189+ if (ret)31903190+ return ret;31913191+31923192+ mdelay(1);31933193+31943194+ /*31953195+ * Write RF buffer31963196+ */31973197+ ret = ath5k_hw_rfregs_init(ah, channel, mode);31983198+ if (ret)31993199+ return ret;32003200+32013201+ /* Write OFDM timings on 5212*/32023202+ if (ah->ah_version == AR5K_AR5212 &&32033203+ channel->hw_value & CHANNEL_OFDM) {32043204+32053205+ ret = ath5k_hw_write_ofdm_timings(ah, channel);32063206+ if (ret)32073207+ return ret;32083208+32093209+ /* Spur info is available only from EEPROM versions32103210+ * greater than 5.3, but the EEPROM routines will use32113211+ * static values for older versions */32123212+ if (ah->ah_mac_srev >= AR5K_SREV_AR5424)32133213+ ath5k_hw_set_spur_mitigation_filter(ah,32143214+ channel);32153215+ }32163216+32173217+ /*Enable/disable 802.11b mode on 511132183218+ (enable 2111 frequency converter + CCK)*/32193219+ if (ah->ah_radio == AR5K_RF5111) {32203220+ if (mode == AR5K_MODE_11B)32213221+ AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,32223222+ AR5K_TXCFG_B_MODE);32233223+ else32243224+ AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,32253225+ AR5K_TXCFG_B_MODE);32263226+ }32273227+32283228+ } else if (ah->ah_version == AR5K_AR5210) {32293229+ mdelay(1);32303230+ /* Disable phy and wait */32313231+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);32323232+ mdelay(1);32333233+ }32343234+32353235+ /* Set channel on PHY */32363236+ ret = ath5k_hw_channel(ah, channel);32373237+ if (ret)32383238+ return ret;32393239+32403240+ /*32413241+ * Enable the PHY and wait until completion32423242+ * This includes BaseBand and Synthesizer32433243+ * activation.32443244+ */32453245+ ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);32463246+32473247+ /*32483248+ * On 5211+ read activation -> rx delay32493249+ * and use it.32503250+ */32513251+ if (ah->ah_version != AR5K_AR5210) {32523252+ u32 delay;32533253+ delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &32543254+ AR5K_PHY_RX_DELAY_M;32553255+ delay = (channel->hw_value & CHANNEL_CCK) ?32563256+ ((delay << 2) / 22) : (delay / 10);32573257+ if (ah->ah_bwmode == AR5K_BWMODE_10MHZ)32583258+ delay = delay << 1;32593259+ if (ah->ah_bwmode == AR5K_BWMODE_5MHZ)32603260+ delay = delay << 2;32613261+ /* XXX: /2 on turbo ? Let's be safe32623262+ * for now */32633263+ udelay(100 + delay);32643264+ } else {32653265+ mdelay(1);32663266+ }32673267+32683268+ if (fast)32693269+ /*32703270+ * Release RF Bus grant32713271+ */32723272+ AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,32733273+ AR5K_PHY_RFBUS_REQ_REQUEST);32743274+ else {32753275+ /*32763276+ * Perform ADC test to see if baseband is ready32773277+ * Set tx hold and check adc test register32783278+ */32793279+ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);32803280+ ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);32813281+ for (i = 0; i <= 20; i++) {32823282+ if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))32833283+ break;32843284+ udelay(200);32853285+ }32863286+ ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);32873287+ }32883288+32893289+ /*32903290+ * Start automatic gain control calibration32913291+ *32923292+ * During AGC calibration RX path is re-routed to32933293+ * a power detector so we don't receive anything.32943294+ *32953295+ * This method is used to calibrate some static offsets32963296+ * used together with on-the fly I/Q calibration (the32973297+ * one performed via ath5k_hw_phy_calibrate), which doesn't32983298+ * interrupt rx path.32993299+ *33003300+ * While rx path is re-routed to the power detector we also33013301+ * start a noise floor calibration to measure the33023302+ * card's noise floor (the noise we measure when we are not33033303+ * transmitting or receiving anything).33043304+ *33053305+ * If we are in a noisy environment, AGC calibration may time33063306+ * out and/or noise floor calibration might timeout.33073307+ */33083308+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,33093309+ AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);33103310+33113311+ /* At the same time start I/Q calibration for QAM constellation33123312+ * -no need for CCK- */33133313+ ah->ah_calibration = false;33143314+ if (!(mode == AR5K_MODE_11B)) {33153315+ ah->ah_calibration = true;33163316+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,33173317+ AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);33183318+ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,33193319+ AR5K_PHY_IQ_RUN);33203320+ }33213321+33223322+ /* Wait for gain calibration to finish (we check for I/Q calibration33233323+ * during ath5k_phy_calibrate) */33243324+ if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,33253325+ AR5K_PHY_AGCCTL_CAL, 0, false)) {33263326+ ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",33273327+ channel->center_freq);33283328+ }33293329+33303330+ /* Restore antenna mode */33313331+ ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);33323332+33333333+ return ret;32333334}
+412-280
drivers/net/wireless/ath/ath5k/qcu.c
···2525#include "debug.h"2626#include "base.h"27272828+2929+/******************\3030+* Helper functions *3131+\******************/3232+2833/*2929- * Get properties for a transmit queue3434+ * Get number of pending frames3535+ * for a specific queue [5211+]3036 */3131-int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,3232- struct ath5k_txq_info *queue_info)3737+u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)3338{3434- memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));3535- return 0;3939+ u32 pending;4040+ AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);4141+4242+ /* Return if queue is declared inactive */4343+ if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)4444+ return false;4545+4646+ /* XXX: How about AR5K_CFG_TXCNT ? */4747+ if (ah->ah_version == AR5K_AR5210)4848+ return false;4949+5050+ pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));5151+ pending &= AR5K_QCU_STS_FRMPENDCNT;5252+5353+ /* It's possible to have no frames pending even if TXE5454+ * is set. To indicate that q has not stopped return5555+ * true */5656+ if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))5757+ return true;5858+5959+ return pending;6060+}6161+6262+/*6363+ * Set a transmit queue inactive6464+ */6565+void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)6666+{6767+ if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))6868+ return;6969+7070+ /* This queue will be skipped in further operations */7171+ ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;7272+ /*For SIMR setup*/7373+ AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);3674}37753876/*···8547 cw = (cw << 1) | 1;86488749 return cw;5050+}5151+5252+/*5353+ * Get properties for a transmit queue5454+ */5555+int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,5656+ struct ath5k_txq_info *queue_info)5757+{5858+ memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));5959+ return 0;8860}89619062/*···220172 return queue;221173}222174223223-/*224224- * Get number of pending frames225225- * for a specific queue [5211+]226226- */227227-u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)228228-{229229- u32 pending;230230- AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);231175232232- /* Return if queue is declared inactive */233233- if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)234234- return false;235235-236236- /* XXX: How about AR5K_CFG_TXCNT ? */237237- if (ah->ah_version == AR5K_AR5210)238238- return false;239239-240240- pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));241241- pending &= AR5K_QCU_STS_FRMPENDCNT;242242-243243- /* It's possible to have no frames pending even if TXE244244- * is set. To indicate that q has not stopped return245245- * true */246246- if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))247247- return true;248248-249249- return pending;250250-}176176+/*******************************\177177+* Single QCU/DCU initialization *178178+\*******************************/251179252180/*253253- * Set a transmit queue inactive181181+ * Set tx retry limits on DCU254182 */255255-void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)256256-{257257- if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))258258- return;259259-260260- /* This queue will be skipped in further operations */261261- ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;262262- /*For SIMR setup*/263263- AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);264264-}265265-266266-/*267267- * Set DFS properties for a transmit queue on DCU268268- */269269-int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)183183+static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah,184184+ unsigned int queue)270185{271186 u32 retry_lg, retry_sh;272272- struct ath5k_txq_info *tq = &ah->ah_txq[queue];273273-274274- AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);275275-276276- tq = &ah->ah_txq[queue];277277-278278- if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)279279- return 0;280280-281281- if (ah->ah_version == AR5K_AR5210) {282282- /* Only handle data queues, others will be ignored */283283- if (tq->tqi_type != AR5K_TX_QUEUE_DATA)284284- return 0;285285-286286- /* Set Slot time */287287- ath5k_hw_reg_write(ah, ah->ah_turbo ?288288- AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,289289- AR5K_SLOT_TIME);290290- /* Set ACK_CTS timeout */291291- ath5k_hw_reg_write(ah, ah->ah_turbo ?292292- AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :293293- AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);294294- /* Set Transmit Latency */295295- ath5k_hw_reg_write(ah, ah->ah_turbo ?296296- AR5K_INIT_TRANSMIT_LATENCY_TURBO :297297- AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);298298-299299- /* Set IFS0 */300300- if (ah->ah_turbo) {301301- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +302302- tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) <<303303- AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,304304- AR5K_IFS0);305305- } else {306306- ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +307307- tq->tqi_aifs * AR5K_INIT_SLOT_TIME) <<308308- AR5K_IFS0_DIFS_S) |309309- AR5K_INIT_SIFS, AR5K_IFS0);310310- }311311-312312- /* Set IFS1 */313313- ath5k_hw_reg_write(ah, ah->ah_turbo ?314314- AR5K_INIT_PROTO_TIME_CNTRL_TURBO :315315- AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);316316- /* Set AR5K_PHY_SETTLING */317317- ath5k_hw_reg_write(ah, ah->ah_turbo ?318318- (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)319319- | 0x38 :320320- (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)321321- | 0x1C,322322- AR5K_PHY_SETTLING);323323- /* Set Frame Control Register */324324- ath5k_hw_reg_write(ah, ah->ah_turbo ?325325- (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |326326- AR5K_PHY_TURBO_SHORT | 0x2020) :327327- (AR5K_PHY_FRAME_CTL_INI | 0x1020),328328- AR5K_PHY_FRAME_CTL_5210);329329- }330187331188 /*332189 * Calculate and set retry limits···246293 retry_sh = AR5K_INIT_SH_RETRY;247294 }248295249249- /*No QCU/DCU [5210]*/296296+ /* Single data queue on AR5210 */250297 if (ah->ah_version == AR5K_AR5210) {298298+ struct ath5k_txq_info *tq = &ah->ah_txq[queue];299299+300300+ if (queue > 0)301301+ return;302302+251303 ath5k_hw_reg_write(ah,252304 (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)253305 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,···262304 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)263305 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),264306 AR5K_NODCU_RETRY_LMT);307307+ /* DCU on AR5211+ */265308 } else {266266- /*QCU/DCU [5211+]*/267309 ath5k_hw_reg_write(ah,268310 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,269311 AR5K_DCU_RETRY_LMT_SLG_RETRY) |···272314 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |273315 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),274316 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));317317+ }318318+ return;319319+}275320276276- /*===Rest is also for QCU/DCU only [5211+]===*/321321+/**322322+ * ath5k_hw_reset_tx_queue - Initialize a single hw queue323323+ *324324+ * @ah The &struct ath5k_hw325325+ * @queue The hw queue number326326+ *327327+ * Set DFS properties for the given transmit queue on DCU328328+ * and configures all queue-specific parameters.329329+ */330330+int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)331331+{332332+ struct ath5k_txq_info *tq = &ah->ah_txq[queue];277333278278- /*279279- * Set contention window (cw_min/cw_max)280280- * and arbitrated interframe space (aifs)...281281- */282282- ath5k_hw_reg_write(ah,283283- AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |284284- AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |285285- AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),286286- AR5K_QUEUE_DFS_LOCAL_IFS(queue));334334+ AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);287335288288- /*289289- * Set misc registers290290- */291291- /* Enable DCU early termination for this queue */292292- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),293293- AR5K_QCU_MISC_DCU_EARLY);336336+ tq = &ah->ah_txq[queue];294337295295- /* Enable DCU to wait for next fragment from QCU */338338+ /* Skip if queue inactive or if we are on AR5210339339+ * that doesn't have QCU/DCU */340340+ if ((ah->ah_version == AR5K_AR5210) ||341341+ (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE))342342+ return 0;343343+344344+ /*345345+ * Set contention window (cw_min/cw_max)346346+ * and arbitrated interframe space (aifs)...347347+ */348348+ ath5k_hw_reg_write(ah,349349+ AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |350350+ AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |351351+ AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS),352352+ AR5K_QUEUE_DFS_LOCAL_IFS(queue));353353+354354+ /*355355+ * Set tx retry limits for this queue356356+ */357357+ ath5k_hw_set_tx_retry_limits(ah, queue);358358+359359+360360+ /*361361+ * Set misc registers362362+ */363363+364364+ /* Enable DCU to wait for next fragment from QCU */365365+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),366366+ AR5K_DCU_MISC_FRAG_WAIT);367367+368368+ /* On Maui and Spirit use the global seqnum on DCU */369369+ if (ah->ah_mac_version < AR5K_SREV_AR5211)296370 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),297297- AR5K_DCU_MISC_FRAG_WAIT);371371+ AR5K_DCU_MISC_SEQNUM_CTL);298372299299- /* On Maui and Spirit use the global seqnum on DCU */300300- if (ah->ah_mac_version < AR5K_SREV_AR5211)301301- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),302302- AR5K_DCU_MISC_SEQNUM_CTL);373373+ /* Constant bit rate period */374374+ if (tq->tqi_cbr_period) {375375+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,376376+ AR5K_QCU_CBRCFG_INTVAL) |377377+ AR5K_REG_SM(tq->tqi_cbr_overflow_limit,378378+ AR5K_QCU_CBRCFG_ORN_THRES),379379+ AR5K_QUEUE_CBRCFG(queue));303380304304- if (tq->tqi_cbr_period) {305305- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,306306- AR5K_QCU_CBRCFG_INTVAL) |307307- AR5K_REG_SM(tq->tqi_cbr_overflow_limit,308308- AR5K_QCU_CBRCFG_ORN_THRES),309309- AR5K_QUEUE_CBRCFG(queue));381381+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),382382+ AR5K_QCU_MISC_FRSHED_CBR);383383+384384+ if (tq->tqi_cbr_overflow_limit)310385 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),311311- AR5K_QCU_MISC_FRSHED_CBR);312312- if (tq->tqi_cbr_overflow_limit)313313- AR5K_REG_ENABLE_BITS(ah,314314- AR5K_QUEUE_MISC(queue),315386 AR5K_QCU_MISC_CBR_THRES_ENABLE);316316- }387387+ }317388318318- if (tq->tqi_ready_time &&319319- (tq->tqi_type != AR5K_TX_QUEUE_CAB))320320- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,321321- AR5K_QCU_RDYTIMECFG_INTVAL) |322322- AR5K_QCU_RDYTIMECFG_ENABLE,323323- AR5K_QUEUE_RDYTIMECFG(queue));389389+ /* Ready time interval */390390+ if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB))391391+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,392392+ AR5K_QCU_RDYTIMECFG_INTVAL) |393393+ AR5K_QCU_RDYTIMECFG_ENABLE,394394+ AR5K_QUEUE_RDYTIMECFG(queue));324395325325- if (tq->tqi_burst_time) {326326- ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,327327- AR5K_DCU_CHAN_TIME_DUR) |328328- AR5K_DCU_CHAN_TIME_ENABLE,329329- AR5K_QUEUE_DFS_CHANNEL_TIME(queue));396396+ if (tq->tqi_burst_time) {397397+ ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,398398+ AR5K_DCU_CHAN_TIME_DUR) |399399+ AR5K_DCU_CHAN_TIME_ENABLE,400400+ AR5K_QUEUE_DFS_CHANNEL_TIME(queue));330401331331- if (tq->tqi_flags332332- & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)333333- AR5K_REG_ENABLE_BITS(ah,334334- AR5K_QUEUE_MISC(queue),335335- AR5K_QCU_MISC_RDY_VEOL_POLICY);336336- }337337-338338- if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)339339- ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,340340- AR5K_QUEUE_DFS_MISC(queue));341341-342342- if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)343343- ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,344344- AR5K_QUEUE_DFS_MISC(queue));345345-346346- /*347347- * Set registers by queue type348348- */349349- switch (tq->tqi_type) {350350- case AR5K_TX_QUEUE_BEACON:402402+ if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)351403 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),404404+ AR5K_QCU_MISC_RDY_VEOL_POLICY);405405+ }406406+407407+ /* Enable/disable Post frame backoff */408408+ if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)409409+ ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,410410+ AR5K_QUEUE_DFS_MISC(queue));411411+412412+ /* Enable/disable fragmentation burst backoff */413413+ if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)414414+ ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,415415+ AR5K_QUEUE_DFS_MISC(queue));416416+417417+ /*418418+ * Set registers by queue type419419+ */420420+ switch (tq->tqi_type) {421421+ case AR5K_TX_QUEUE_BEACON:422422+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),352423 AR5K_QCU_MISC_FRSHED_DBA_GT |353424 AR5K_QCU_MISC_CBREXP_BCN_DIS |354425 AR5K_QCU_MISC_BCN_ENABLE);355426356356- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),427427+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),357428 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<358429 AR5K_DCU_MISC_ARBLOCK_CTL_S) |359430 AR5K_DCU_MISC_ARBLOCK_IGNORE |360431 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |361432 AR5K_DCU_MISC_BCN_ENABLE);362362- break;433433+ break;363434364364- case AR5K_TX_QUEUE_CAB:365365- /* XXX: use BCN_SENT_GT, if we can figure out how */366366- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),367367- AR5K_QCU_MISC_FRSHED_DBA_GT |368368- AR5K_QCU_MISC_CBREXP_DIS |369369- AR5K_QCU_MISC_CBREXP_BCN_DIS);435435+ case AR5K_TX_QUEUE_CAB:436436+ /* XXX: use BCN_SENT_GT, if we can figure out how */437437+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),438438+ AR5K_QCU_MISC_FRSHED_DBA_GT |439439+ AR5K_QCU_MISC_CBREXP_DIS |440440+ AR5K_QCU_MISC_CBREXP_BCN_DIS);370441371371- ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -372372- (AR5K_TUNE_SW_BEACON_RESP -373373- AR5K_TUNE_DMA_BEACON_RESP) -442442+ ath5k_hw_reg_write(ah, ((tq->tqi_ready_time -443443+ (AR5K_TUNE_SW_BEACON_RESP -444444+ AR5K_TUNE_DMA_BEACON_RESP) -374445 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |375375- AR5K_QCU_RDYTIMECFG_ENABLE,376376- AR5K_QUEUE_RDYTIMECFG(queue));446446+ AR5K_QCU_RDYTIMECFG_ENABLE,447447+ AR5K_QUEUE_RDYTIMECFG(queue));377448378378- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),379379- (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<380380- AR5K_DCU_MISC_ARBLOCK_CTL_S));449449+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),450450+ (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<451451+ AR5K_DCU_MISC_ARBLOCK_CTL_S));452452+ break;453453+454454+ case AR5K_TX_QUEUE_UAPSD:455455+ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),456456+ AR5K_QCU_MISC_CBREXP_DIS);457457+ break;458458+459459+ case AR5K_TX_QUEUE_DATA:460460+ default:381461 break;382382-383383- case AR5K_TX_QUEUE_UAPSD:384384- AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),385385- AR5K_QCU_MISC_CBREXP_DIS);386386- break;387387-388388- case AR5K_TX_QUEUE_DATA:389389- default:390390- break;391391- }392392-393393- /* TODO: Handle frame compression */394394-395395- /*396396- * Enable interrupts for this tx queue397397- * in the secondary interrupt mask registers398398- */399399- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)400400- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);401401-402402- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)403403- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);404404-405405- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)406406- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);407407-408408- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)409409- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);410410-411411- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)412412- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);413413-414414- if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)415415- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);416416-417417- if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)418418- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);419419-420420- if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)421421- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);422422-423423- if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)424424- AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);425425-426426- /* Update secondary interrupt mask registers */427427-428428- /* Filter out inactive queues */429429- ah->ah_txq_imr_txok &= ah->ah_txq_status;430430- ah->ah_txq_imr_txerr &= ah->ah_txq_status;431431- ah->ah_txq_imr_txurn &= ah->ah_txq_status;432432- ah->ah_txq_imr_txdesc &= ah->ah_txq_status;433433- ah->ah_txq_imr_txeol &= ah->ah_txq_status;434434- ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;435435- ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;436436- ah->ah_txq_imr_qtrig &= ah->ah_txq_status;437437- ah->ah_txq_imr_nofrm &= ah->ah_txq_status;438438-439439- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,440440- AR5K_SIMR0_QCU_TXOK) |441441- AR5K_REG_SM(ah->ah_txq_imr_txdesc,442442- AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);443443- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,444444- AR5K_SIMR1_QCU_TXERR) |445445- AR5K_REG_SM(ah->ah_txq_imr_txeol,446446- AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);447447- /* Update simr2 but don't overwrite rest simr2 settings */448448- AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);449449- AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,450450- AR5K_REG_SM(ah->ah_txq_imr_txurn,451451- AR5K_SIMR2_QCU_TXURN));452452- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,453453- AR5K_SIMR3_QCBRORN) |454454- AR5K_REG_SM(ah->ah_txq_imr_cbrurn,455455- AR5K_SIMR3_QCBRURN), AR5K_SIMR3);456456- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,457457- AR5K_SIMR4_QTRIG), AR5K_SIMR4);458458- /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */459459- ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,460460- AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);461461- /* No queue has TXNOFRM enabled, disable the interrupt462462- * by setting AR5K_TXNOFRM to zero */463463- if (ah->ah_txq_imr_nofrm == 0)464464- ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);465465-466466- /* Set QCU mask for this DCU to save power */467467- AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);468462 }463463+464464+ /* TODO: Handle frame compression */465465+466466+ /*467467+ * Enable interrupts for this tx queue468468+ * in the secondary interrupt mask registers469469+ */470470+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)471471+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);472472+473473+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)474474+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);475475+476476+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)477477+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);478478+479479+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)480480+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);481481+482482+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)483483+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);484484+485485+ if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)486486+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);487487+488488+ if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)489489+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);490490+491491+ if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)492492+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);493493+494494+ if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)495495+ AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);496496+497497+ /* Update secondary interrupt mask registers */498498+499499+ /* Filter out inactive queues */500500+ ah->ah_txq_imr_txok &= ah->ah_txq_status;501501+ ah->ah_txq_imr_txerr &= ah->ah_txq_status;502502+ ah->ah_txq_imr_txurn &= ah->ah_txq_status;503503+ ah->ah_txq_imr_txdesc &= ah->ah_txq_status;504504+ ah->ah_txq_imr_txeol &= ah->ah_txq_status;505505+ ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;506506+ ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;507507+ ah->ah_txq_imr_qtrig &= ah->ah_txq_status;508508+ ah->ah_txq_imr_nofrm &= ah->ah_txq_status;509509+510510+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,511511+ AR5K_SIMR0_QCU_TXOK) |512512+ AR5K_REG_SM(ah->ah_txq_imr_txdesc,513513+ AR5K_SIMR0_QCU_TXDESC),514514+ AR5K_SIMR0);515515+516516+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,517517+ AR5K_SIMR1_QCU_TXERR) |518518+ AR5K_REG_SM(ah->ah_txq_imr_txeol,519519+ AR5K_SIMR1_QCU_TXEOL),520520+ AR5K_SIMR1);521521+522522+ /* Update SIMR2 but don't overwrite rest simr2 settings */523523+ AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);524524+ AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,525525+ AR5K_REG_SM(ah->ah_txq_imr_txurn,526526+ AR5K_SIMR2_QCU_TXURN));527527+528528+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,529529+ AR5K_SIMR3_QCBRORN) |530530+ AR5K_REG_SM(ah->ah_txq_imr_cbrurn,531531+ AR5K_SIMR3_QCBRURN),532532+ AR5K_SIMR3);533533+534534+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,535535+ AR5K_SIMR4_QTRIG), AR5K_SIMR4);536536+537537+ /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */538538+ ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,539539+ AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);540540+541541+ /* No queue has TXNOFRM enabled, disable the interrupt542542+ * by setting AR5K_TXNOFRM to zero */543543+ if (ah->ah_txq_imr_nofrm == 0)544544+ ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);545545+546546+ /* Set QCU mask for this DCU to save power */547547+ AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);469548470549 return 0;471550}472551473473-/*474474- * Set slot time on DCU552552+553553+/**************************\554554+* Global QCU/DCU functions *555555+\**************************/556556+557557+/**558558+ * ath5k_hw_set_ifs_intervals - Set global inter-frame spaces on DCU559559+ *560560+ * @ah The &struct ath5k_hw561561+ * @slot_time Slot time in us562562+ *563563+ * Sets the global IFS intervals on DCU (also works on AR5210) for564564+ * the given slot time and the current bwmode.475565 */476476-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)566566+int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time)477567{568568+ struct ieee80211_channel *channel = ah->ah_current_channel;569569+ struct ath5k_softc *sc = ah->ah_sc;570570+ struct ieee80211_rate *rate;571571+ u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock;478572 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);479573480574 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)481575 return -EINVAL;482576483483- if (ah->ah_version == AR5K_AR5210)484484- ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);577577+ sifs = ath5k_hw_get_default_sifs(ah);578578+ sifs_clock = ath5k_hw_htoclock(ah, sifs);579579+580580+ /* EIFS581581+ * Txtime of ack at lowest rate + SIFS + DIFS582582+ * (DIFS = SIFS + 2 * Slot time)583583+ *584584+ * Note: HAL has some predefined values for EIFS585585+ * Turbo: (37 + 2 * 6)586586+ * Default: (74 + 2 * 9)587587+ * Half: (149 + 2 * 13)588588+ * Quarter: (298 + 2 * 21)589589+ *590590+ * (74 + 2 * 6) for AR5210 default and turbo !591591+ *592592+ * According to the formula we have593593+ * ack_tx_time = 25 for turbo and594594+ * ack_tx_time = 42.5 * clock multiplier595595+ * for default/half/quarter.596596+ *597597+ * This can't be right, 42 is what we would get598598+ * from ath5k_hw_get_frame_dur_for_bwmode or599599+ * ieee80211_generic_frame_duration for zero frame600600+ * length and without SIFS !601601+ *602602+ * Also we have different lowest rate for 802.11a603603+ */604604+ if (channel->hw_value & CHANNEL_5GHZ)605605+ rate = &sc->sbands[IEEE80211_BAND_5GHZ].bitrates[0];485606 else486486- ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);607607+ rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];608608+609609+ ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);610610+611611+ /* ack_tx_time includes an SIFS already */612612+ eifs = ack_tx_time + sifs + 2 * slot_time;613613+ eifs_clock = ath5k_hw_htoclock(ah, eifs);614614+615615+ /* Set IFS settings on AR5210 */616616+ if (ah->ah_version == AR5K_AR5210) {617617+ u32 pifs, pifs_clock, difs, difs_clock;618618+619619+ /* Set slot time */620620+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);621621+622622+ /* Set EIFS */623623+ eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS);624624+625625+ /* PIFS = Slot time + SIFS */626626+ pifs = slot_time + sifs;627627+ pifs_clock = ath5k_hw_htoclock(ah, pifs);628628+ pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS);629629+630630+ /* DIFS = SIFS + 2 * Slot time */631631+ difs = sifs + 2 * slot_time;632632+ difs_clock = ath5k_hw_htoclock(ah, difs);633633+634634+ /* Set SIFS/DIFS */635635+ ath5k_hw_reg_write(ah, (difs_clock <<636636+ AR5K_IFS0_DIFS_S) | sifs_clock,637637+ AR5K_IFS0);638638+639639+ /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */640640+ ath5k_hw_reg_write(ah, pifs_clock | eifs_clock |641641+ (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S),642642+ AR5K_IFS1);643643+644644+ return 0;645645+ }646646+647647+ /* Set IFS slot time */648648+ ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);649649+650650+ /* Set EIFS interval */651651+ ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS);652652+653653+ /* Set SIFS interval in usecs */654654+ AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,655655+ AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC,656656+ sifs);657657+658658+ /* Set SIFS interval in clock cycles */659659+ ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS);487660488661 return 0;489662}490663664664+665665+int ath5k_hw_init_queues(struct ath5k_hw *ah)666666+{667667+ int i, ret;668668+669669+ /* TODO: HW Compression support for data queues */670670+ /* TODO: Burst prefetch for data queues */671671+672672+ /*673673+ * Reset queues and start beacon timers at the end of the reset routine674674+ * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping675675+ * Note: If we want we can assign multiple qcus on one dcu.676676+ */677677+ if (ah->ah_version != AR5K_AR5210)678678+ for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {679679+ ret = ath5k_hw_reset_tx_queue(ah, i);680680+ if (ret) {681681+ ATH5K_ERR(ah->ah_sc,682682+ "failed to reset TX queue #%d\n", i);683683+ return ret;684684+ }685685+ }686686+ else687687+ /* No QCU/DCU on AR5210, just set tx688688+ * retry limits. We set IFS parameters689689+ * on ath5k_hw_set_ifs_intervals */690690+ ath5k_hw_set_tx_retry_limits(ah, 0);691691+692692+ /* Set the turbo flag when operating on 40MHz */693693+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)694694+ AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,695695+ AR5K_DCU_GBL_IFS_MISC_TURBO_MODE);696696+697697+ /* If we didn't set IFS timings through698698+ * ath5k_hw_set_coverage_class make sure699699+ * we set them here */700700+ if (!ah->ah_coverage_class) {701701+ unsigned int slot_time = ath5k_hw_get_default_slottime(ah);702702+ ath5k_hw_set_ifs_intervals(ah, slot_time);703703+ }704704+705705+ return 0;706706+}
···27272828#include <linux/pci.h> /* To determine if a card is pci-e */2929#include <linux/log2.h>3030+#include <linux/platform_device.h>3031#include "ath5k.h"3132#include "reg.h"3233#include "base.h"3334#include "debug.h"3535+3636+3737+/******************\3838+* Helper functions *3939+\******************/34403541/*3642 * Check if a register write has been completed···5953 return (i <= 0) ? -EAGAIN : 0;6054}61555656+5757+/*************************\5858+* Clock related functions *5959+\*************************/6060+6261/**6363- * ath5k_hw_write_ofdm_timings - set OFDM timings on AR52126262+ * ath5k_hw_htoclock - Translate usec to hw clock units6463 *6565- * @ah: the &struct ath5k_hw6666- * @channel: the currently set channel upon reset6767- *6868- * Write the delta slope coefficient (used on pilot tracking ?) for OFDM6969- * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().7070- *7171- * Since delta slope is floating point we split it on its exponent and7272- * mantissa and provide these values on hw.7373- *7474- * For more infos i think this patent is related7575- * http://www.freepatentsonline.com/7184495.html6464+ * @ah: The &struct ath5k_hw6565+ * @usec: value in microseconds7666 */7777-static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,7878- struct ieee80211_channel *channel)6767+unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)7968{8080- /* Get exponent and mantissa and set it */8181- u32 coef_scaled, coef_exp, coef_man,8282- ds_coef_exp, ds_coef_man, clock;8383-8484- BUG_ON(!(ah->ah_version == AR5K_AR5212) ||8585- !(channel->hw_value & CHANNEL_OFDM));8686-8787- /* Get coefficient8888- * ALGO: coef = (5 * clock / carrier_freq) / 28989- * we scale coef by shifting clock value by 24 for9090- * better precision since we use integers */9191- /* TODO: Half/quarter rate */9292- clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;9393- coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;9494-9595- /* Get exponent9696- * ALGO: coef_exp = 14 - highest set bit position */9797- coef_exp = ilog2(coef_scaled);9898-9999- /* Doesn't make sense if it's zero*/100100- if (!coef_scaled || !coef_exp)101101- return -EINVAL;102102-103103- /* Note: we've shifted coef_scaled by 24 */104104- coef_exp = 14 - (coef_exp - 24);105105-106106-107107- /* Get mantissa (significant digits)108108- * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */109109- coef_man = coef_scaled +110110- (1 << (24 - coef_exp - 1));111111-112112- /* Calculate delta slope coefficient exponent113113- * and mantissa (remove scaling) and set them on hw */114114- ds_coef_man = coef_man >> (24 - coef_exp);115115- ds_coef_exp = coef_exp - 16;116116-117117- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,118118- AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);119119- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,120120- AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);121121-122122- return 0;6969+ struct ath_common *common = ath5k_hw_common(ah);7070+ return usec * common->clockrate;12371}12472125125-126126-/*127127- * index into rates for control rates, we can set it up like this because128128- * this is only used for AR5212 and we know it supports G mode7373+/**7474+ * ath5k_hw_clocktoh - Translate hw clock units to usec7575+ * @clock: value in hw clock units12976 */130130-static const unsigned int control_rates[] =131131- { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };7777+unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)7878+{7979+ struct ath_common *common = ath5k_hw_common(ah);8080+ return clock / common->clockrate;8181+}1328213383/**134134- * ath5k_hw_write_rate_duration - fill rate code to duration table8484+ * ath5k_hw_init_core_clock - Initialize core clock13585 *136136- * @ah: the &struct ath5k_hw137137- * @mode: one of enum ath5k_driver_mode8686+ * @ah The &struct ath5k_hw13887 *139139- * Write the rate code to duration table upon hw reset. This is a helper for140140- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on141141- * the hardware, based on current mode, for each rate. The rates which are142142- * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have143143- * different rate code so we write their value twice (one for long preample144144- * and one for short).145145- *146146- * Note: Band doesn't matter here, if we set the values for OFDM it works147147- * on both a and g modes. So all we have to do is set values for all g rates148148- * that include all OFDM and CCK rates. If we operate in turbo or xr/half/149149- * quarter rate mode, we need to use another set of bitrates (that's why we150150- * need the mode parameter) but we don't handle these proprietary modes yet.8888+ * Initialize core clock parameters (usec, usec32, latencies etc).15189 */152152-static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,153153- unsigned int mode)9090+static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)15491{155155- struct ath5k_softc *sc = ah->ah_sc;156156- struct ieee80211_rate *rate;157157- unsigned int i;9292+ struct ieee80211_channel *channel = ah->ah_current_channel;9393+ struct ath_common *common = ath5k_hw_common(ah);9494+ u32 usec_reg, txlat, rxlat, usec, clock, sclock, txf2txs;15895159159- /* Write rate duration table */160160- for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {161161- u32 reg;162162- u16 tx_time;9696+ /*9797+ * Set core clock frequency9898+ */9999+ if (channel->hw_value & CHANNEL_5GHZ)100100+ clock = 40; /* 802.11a */101101+ else if (channel->hw_value & CHANNEL_CCK)102102+ clock = 22; /* 802.11b */103103+ else104104+ clock = 44; /* 802.11g */163105164164- rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];106106+ /* Use clock multiplier for non-default107107+ * bwmode */108108+ switch (ah->ah_bwmode) {109109+ case AR5K_BWMODE_40MHZ:110110+ clock *= 2;111111+ break;112112+ case AR5K_BWMODE_10MHZ:113113+ clock /= 2;114114+ break;115115+ case AR5K_BWMODE_5MHZ:116116+ clock /= 4;117117+ break;118118+ default:119119+ break;120120+ }165121166166- /* Set ACK timeout */167167- reg = AR5K_RATE_DUR(rate->hw_value);122122+ common->clockrate = clock;168123169169- /* An ACK frame consists of 10 bytes. If you add the FCS,170170- * which ieee80211_generic_frame_duration() adds,171171- * its 14 bytes. Note we use the control rate and not the172172- * actual rate for this rate. See mac80211 tx.c173173- * ieee80211_duration() for a brief description of174174- * what rate we should choose to TX ACKs. */175175- tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,176176- NULL, 10, rate));124124+ /*125125+ * Set USEC parameters126126+ */127127+ /* Set USEC counter on PCU*/128128+ usec = clock - 1;129129+ usec = AR5K_REG_SM(usec, AR5K_USEC_1);177130178178- ath5k_hw_reg_write(ah, tx_time, reg);131131+ /* Set usec duration on DCU */132132+ if (ah->ah_version != AR5K_AR5210)133133+ AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC,134134+ AR5K_DCU_GBL_IFS_MISC_USEC_DUR,135135+ clock);179136180180- if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))181181- continue;137137+ /* Set 32MHz USEC counter */138138+ if ((ah->ah_radio == AR5K_RF5112) ||139139+ (ah->ah_radio == AR5K_RF5413) ||140140+ (ah->ah_radio == AR5K_RF2316) ||141141+ (ah->ah_radio == AR5K_RF2317))142142+ /* Remain on 40MHz clock ? */143143+ sclock = 40 - 1;144144+ else145145+ sclock = 32 - 1;146146+ sclock = AR5K_REG_SM(sclock, AR5K_USEC_32);182147183183- /*184184- * We're not distinguishing short preamble here,185185- * This is true, all we'll get is a longer value here186186- * which is not necessarilly bad. We could use187187- * export ieee80211_frame_duration() but that needs to be188188- * fixed first to be properly used by mac802111 drivers:148148+ /*149149+ * Set tx/rx latencies150150+ */151151+ usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);152152+ txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);153153+ rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);154154+155155+ /*156156+ * 5210 initvals don't include usec settings157157+ * so we need to use magic values here for158158+ * tx/rx latencies159159+ */160160+ if (ah->ah_version == AR5K_AR5210) {161161+ /* same for turbo */162162+ txlat = AR5K_INIT_TX_LATENCY_5210;163163+ rxlat = AR5K_INIT_RX_LATENCY_5210;164164+ }165165+166166+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {167167+ /* 5311 has different tx/rx latency masks168168+ * from 5211, since we deal 5311 the same169169+ * as 5211 when setting initvals, shift170170+ * values here to their proper locations189171 *190190- * - remove erp stuff and let the routine figure ofdm191191- * erp rates192192- * - remove passing argument ieee80211_local as193193- * drivers don't have access to it194194- * - move drivers using ieee80211_generic_frame_duration()195195- * to this196196- */197197- ath5k_hw_reg_write(ah, tx_time,198198- reg + (AR5K_SET_SHORT_PREAMBLE << 2));172172+ * Note: Initvals indicate tx/rx/ latencies173173+ * are the same for turbo mode */174174+ txlat = AR5K_REG_SM(txlat, AR5K_USEC_TX_LATENCY_5210);175175+ rxlat = AR5K_REG_SM(rxlat, AR5K_USEC_RX_LATENCY_5210);176176+ } else177177+ switch (ah->ah_bwmode) {178178+ case AR5K_BWMODE_10MHZ:179179+ txlat = AR5K_REG_SM(txlat * 2,180180+ AR5K_USEC_TX_LATENCY_5211);181181+ rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,182182+ AR5K_USEC_RX_LATENCY_5211);183183+ txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_10MHZ;184184+ break;185185+ case AR5K_BWMODE_5MHZ:186186+ txlat = AR5K_REG_SM(txlat * 4,187187+ AR5K_USEC_TX_LATENCY_5211);188188+ rxlat = AR5K_REG_SM(AR5K_INIT_RX_LAT_MAX,189189+ AR5K_USEC_RX_LATENCY_5211);190190+ txf2txs = AR5K_INIT_TXF2TXD_START_DELAY_5MHZ;191191+ break;192192+ case AR5K_BWMODE_40MHZ:193193+ txlat = AR5K_INIT_TX_LAT_MIN;194194+ rxlat = AR5K_REG_SM(rxlat / 2,195195+ AR5K_USEC_RX_LATENCY_5211);196196+ txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;197197+ break;198198+ default:199199+ break;200200+ }201201+202202+ usec_reg = (usec | sclock | txlat | rxlat);203203+ ath5k_hw_reg_write(ah, usec_reg, AR5K_USEC);204204+205205+ /* On 5112 set tx frane to tx data start delay */206206+ if (ah->ah_radio == AR5K_RF5112) {207207+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL2,208208+ AR5K_PHY_RF_CTL2_TXF2TXD_START,209209+ txf2txs);199210 }200211}212212+213213+/*214214+ * If there is an external 32KHz crystal available, use it215215+ * as ref. clock instead of 32/40MHz clock and baseband clocks216216+ * to save power during sleep or restore normal 32/40MHz217217+ * operation.218218+ *219219+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,220220+ * 123 - 127) require delay on access.221221+ */222222+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)223223+{224224+ struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;225225+ u32 scal, spending;226226+227227+ /* Only set 32KHz settings if we have an external228228+ * 32KHz crystal present */229229+ if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||230230+ AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&231231+ enable) {232232+233233+ /* 1 usec/cycle */234234+ AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);235235+ /* Set up tsf increment on each cycle */236236+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);237237+238238+ /* Set baseband sleep control registers239239+ * and sleep control rate */240240+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);241241+242242+ if ((ah->ah_radio == AR5K_RF5112) ||243243+ (ah->ah_radio == AR5K_RF5413) ||244244+ (ah->ah_radio == AR5K_RF2316) ||245245+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))246246+ spending = 0x14;247247+ else248248+ spending = 0x18;249249+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);250250+251251+ if ((ah->ah_radio == AR5K_RF5112) ||252252+ (ah->ah_radio == AR5K_RF5413) ||253253+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {254254+ ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);255255+ ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);256256+ ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);257257+ ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);258258+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,259259+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);260260+ } else {261261+ ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);262262+ ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);263263+ ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);264264+ ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);265265+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,266266+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);267267+ }268268+269269+ /* Enable sleep clock operation */270270+ AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,271271+ AR5K_PCICFG_SLEEP_CLOCK_EN);272272+273273+ } else {274274+275275+ /* Disable sleep clock operation and276276+ * restore default parameters */277277+ AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,278278+ AR5K_PCICFG_SLEEP_CLOCK_EN);279279+280280+ AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,281281+ AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);282282+283283+ /* Set DAC/ADC delays */284284+ ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);285285+ ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);286286+287287+ if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))288288+ scal = AR5K_PHY_SCAL_32MHZ_2417;289289+ else if (ee->ee_is_hb63)290290+ scal = AR5K_PHY_SCAL_32MHZ_HB63;291291+ else292292+ scal = AR5K_PHY_SCAL_32MHZ;293293+ ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);294294+295295+ ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);296296+ ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);297297+298298+ if ((ah->ah_radio == AR5K_RF5112) ||299299+ (ah->ah_radio == AR5K_RF5413) ||300300+ (ah->ah_radio == AR5K_RF2316) ||301301+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))302302+ spending = 0x14;303303+ else304304+ spending = 0x18;305305+ ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);306306+307307+ /* Set up tsf increment on each cycle */308308+ AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);309309+ }310310+}311311+312312+313313+/*********************\314314+* Reset/Sleep control *315315+\*********************/201316202317/*203318 * Reset chipset···361234362235 return ret;363236}237237+238238+/*239239+ * Reset AHB chipset240240+ * AR5K_RESET_CTL_PCU flag resets WMAC241241+ * AR5K_RESET_CTL_BASEBAND flag resets WBB242242+ */243243+static int ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)244244+{245245+ u32 mask = flags ? flags : ~0U;246246+ volatile u32 *reg;247247+ u32 regval;248248+ u32 val = 0;249249+250250+ /* ah->ah_mac_srev is not available at this point yet */251251+ if (ah->ah_sc->devid >= AR5K_SREV_AR2315_R6) {252252+ reg = (u32 *) AR5K_AR2315_RESET;253253+ if (mask & AR5K_RESET_CTL_PCU)254254+ val |= AR5K_AR2315_RESET_WMAC;255255+ if (mask & AR5K_RESET_CTL_BASEBAND)256256+ val |= AR5K_AR2315_RESET_BB_WARM;257257+ } else {258258+ reg = (u32 *) AR5K_AR5312_RESET;259259+ if (to_platform_device(ah->ah_sc->dev)->id == 0) {260260+ if (mask & AR5K_RESET_CTL_PCU)261261+ val |= AR5K_AR5312_RESET_WMAC0;262262+ if (mask & AR5K_RESET_CTL_BASEBAND)263263+ val |= AR5K_AR5312_RESET_BB0_COLD |264264+ AR5K_AR5312_RESET_BB0_WARM;265265+ } else {266266+ if (mask & AR5K_RESET_CTL_PCU)267267+ val |= AR5K_AR5312_RESET_WMAC1;268268+ if (mask & AR5K_RESET_CTL_BASEBAND)269269+ val |= AR5K_AR5312_RESET_BB1_COLD |270270+ AR5K_AR5312_RESET_BB1_WARM;271271+ }272272+ }273273+274274+ /* Put BB/MAC into reset */275275+ regval = __raw_readl(reg);276276+ __raw_writel(regval | val, reg);277277+ regval = __raw_readl(reg);278278+ udelay(100);279279+280280+ /* Bring BB/MAC out of reset */281281+ __raw_writel(regval & ~val, reg);282282+ regval = __raw_readl(reg);283283+284284+ /*285285+ * Reset configuration register (for hw byte-swap). Note that this286286+ * is only set for big endian. We do the necessary magic in287287+ * AR5K_INIT_CFG.288288+ */289289+ if ((flags & AR5K_RESET_CTL_PCU) == 0)290290+ ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);291291+292292+ return 0;293293+}294294+364295365296/*366297 * Sleep control···519334 u32 bus_flags;520335 int ret;521336337337+ if (ath5k_get_bus_type(ah) == ATH_AHB)338338+ return 0;339339+522340 /* Make sure device is awake */523341 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);524342 if (ret) {···537349 * we ingore that flag for PCI-E cards. On PCI cards538350 * this flag gets cleared after 64 PCI clocks.539351 */540540- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;352352+ bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;541353542354 if (ah->ah_version == AR5K_AR5210) {543355 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |···566378567379/*568380 * Bring up MAC + PHY Chips and program PLL569569- * TODO: Half/Quarter rate support570381 */571382int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)572383{···577390 mode = 0;578391 clock = 0;579392580580- /* Wakeup the device */581581- ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);582582- if (ret) {583583- ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");584584- return ret;393393+ if ((ath5k_get_bus_type(ah) != ATH_AHB) || !initial) {394394+ /* Wakeup the device */395395+ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);396396+ if (ret) {397397+ ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");398398+ return ret;399399+ }585400 }586401587402 /*···594405 * we ingore that flag for PCI-E cards. On PCI cards595406 * this flag gets cleared after 64 PCI clocks.596407 */597597- bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;408408+ bus_flags = (pdev && pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;598409599410 if (ah->ah_version == AR5K_AR5210) {600411 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |···602413 AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);603414 mdelay(2);604415 } else {605605- ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |606606- AR5K_RESET_CTL_BASEBAND | bus_flags);416416+ if (ath5k_get_bus_type(ah) == ATH_AHB)417417+ ret = ath5k_hw_wisoc_reset(ah, AR5K_RESET_CTL_PCU |418418+ AR5K_RESET_CTL_BASEBAND);419419+ else420420+ ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |421421+ AR5K_RESET_CTL_BASEBAND | bus_flags);607422 }608423609424 if (ret) {···622429 return ret;623430 }624431625625- /* ...clear reset control register and pull device out of626626- * warm reset */627627- if (ath5k_hw_nic_reset(ah, 0)) {432432+ /* ...reset configuration regiter on Wisoc ...433433+ * ...clear reset control register and pull device out of434434+ * warm reset on others */435435+ if (ath5k_get_bus_type(ah) == ATH_AHB)436436+ ret = ath5k_hw_wisoc_reset(ah, 0);437437+ else438438+ ret = ath5k_hw_nic_reset(ah, 0);439439+440440+ if (ret) {628441 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");629442 return -EIO;630443 }···665466 * CCK headers) operation. We need to test666467 * this, 5211 might support ofdm-only g after667468 * all, there are also initial register values668668- * in the code for g mode (see initvals.c). */469469+ * in the code for g mode (see initvals.c).470470+ */669471 if (ah->ah_version == AR5K_AR5211)670472 mode |= AR5K_PHY_MODE_MOD_OFDM;671473 else···679479 } else if (flags & CHANNEL_5GHZ) {680480 mode |= AR5K_PHY_MODE_FREQ_5GHZ;681481482482+ /* Different PLL setting for 5413 */682483 if (ah->ah_radio == AR5K_RF5413)683484 clock = AR5K_PHY_PLL_40MHZ_5413;684485 else···697496 return -EINVAL;698497 }699498700700- if (flags & CHANNEL_TURBO)701701- turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;499499+ /*XXX: Can bwmode be used with dynamic mode ?500500+ * (I don't think it supports 44MHz) */501501+ /* On 2425 initvals TURBO_SHORT is not pressent */502502+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {503503+ turbo = AR5K_PHY_TURBO_MODE |504504+ (ah->ah_radio == AR5K_RF2425) ? 0 :505505+ AR5K_PHY_TURBO_SHORT;506506+ } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) {507507+ if (ah->ah_radio == AR5K_RF5413) {508508+ mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?509509+ AR5K_PHY_MODE_HALF_RATE :510510+ AR5K_PHY_MODE_QUARTER_RATE;511511+ } else if (ah->ah_version == AR5K_AR5212) {512512+ clock |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ?513513+ AR5K_PHY_PLL_HALF_RATE :514514+ AR5K_PHY_PLL_QUARTER_RATE;515515+ }516516+ }517517+702518 } else { /* Reset the device */703519704520 /* ...enable Atheros turbo mode if requested */705705- if (flags & CHANNEL_TURBO)521521+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ)706522 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,707523 AR5K_PHY_TURBO);708524 }···740522 return 0;741523}742524743743-/*744744- * If there is an external 32KHz crystal available, use it745745- * as ref. clock instead of 32/40MHz clock and baseband clocks746746- * to save power during sleep or restore normal 32/40MHz747747- * operation.748748- *749749- * XXX: When operating on 32KHz certain PHY registers (27 - 31,750750- * 123 - 127) require delay on access.751751- */752752-static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)753753-{754754- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;755755- u32 scal, spending, usec32;756525757757- /* Only set 32KHz settings if we have an external758758- * 32KHz crystal present */759759- if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||760760- AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&761761- enable) {762762-763763- /* 1 usec/cycle */764764- AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);765765- /* Set up tsf increment on each cycle */766766- AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);767767-768768- /* Set baseband sleep control registers769769- * and sleep control rate */770770- ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);771771-772772- if ((ah->ah_radio == AR5K_RF5112) ||773773- (ah->ah_radio == AR5K_RF5413) ||774774- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))775775- spending = 0x14;776776- else777777- spending = 0x18;778778- ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);779779-780780- if ((ah->ah_radio == AR5K_RF5112) ||781781- (ah->ah_radio == AR5K_RF5413) ||782782- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {783783- ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);784784- ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);785785- ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);786786- ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);787787- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,788788- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);789789- } else {790790- ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);791791- ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);792792- ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);793793- ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);794794- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,795795- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);796796- }797797-798798- /* Enable sleep clock operation */799799- AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,800800- AR5K_PCICFG_SLEEP_CLOCK_EN);801801-802802- } else {803803-804804- /* Disable sleep clock operation and805805- * restore default parameters */806806- AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,807807- AR5K_PCICFG_SLEEP_CLOCK_EN);808808-809809- AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,810810- AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);811811-812812- ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);813813- ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);814814-815815- if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))816816- scal = AR5K_PHY_SCAL_32MHZ_2417;817817- else if (ee->ee_is_hb63)818818- scal = AR5K_PHY_SCAL_32MHZ_HB63;819819- else820820- scal = AR5K_PHY_SCAL_32MHZ;821821- ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);822822-823823- ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);824824- ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);825825-826826- if ((ah->ah_radio == AR5K_RF5112) ||827827- (ah->ah_radio == AR5K_RF5413) ||828828- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))829829- spending = 0x14;830830- else831831- spending = 0x18;832832- ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);833833-834834- if ((ah->ah_radio == AR5K_RF5112) ||835835- (ah->ah_radio == AR5K_RF5413))836836- usec32 = 39;837837- else838838- usec32 = 31;839839- AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);840840-841841- AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);842842- }843843-}526526+/**************************************\527527+* Post-initvals register modifications *528528+\**************************************/844529845530/* TODO: Half/Quarter rate */846531static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,···784663 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,785664 AR5K_TXCFG_DCU_DBL_BUF_DIS);786665787787- /* Set DAC/ADC delays */788788- if (ah->ah_version == AR5K_AR5212) {789789- u32 scal;790790- struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;791791- if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))792792- scal = AR5K_PHY_SCAL_32MHZ_2417;793793- else if (ee->ee_is_hb63)794794- scal = AR5K_PHY_SCAL_32MHZ_HB63;795795- else796796- scal = AR5K_PHY_SCAL_32MHZ;797797- ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);798798- }799799-800666 /* Set fast ADC */801667 if ((ah->ah_radio == AR5K_RF5413) ||802802- (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {668668+ (ah->ah_radio == AR5K_RF2317) ||669669+ (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {803670 u32 fast_adc = true;804671805672 if (channel->center_freq == 2462 ||···815706 }816707817708 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {818818- u32 usec_reg;819819- /* 5311 has different tx/rx latency masks820820- * from 5211, since we deal 5311 the same821821- * as 5211 when setting initvals, shift822822- * values here to their proper locations */823823- usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);824824- ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |825825- AR5K_USEC_32 |826826- AR5K_USEC_TX_LATENCY_5211 |827827- AR5K_REG_SM(29,828828- AR5K_USEC_RX_LATENCY_5210)),829829- AR5K_USEC_5211);830709 /* Clear QCU/DCU clock gating register */831710 ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);832711 /* Set DAC/ADC delays */833833- ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);712712+ ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ_5311,713713+ AR5K_PHY_SCAL);834714 /* Enable PCU FIFO corruption ECO */835715 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,836716 AR5K_DIAG_SW_ECO_ENABLE);717717+ }718718+719719+ if (ah->ah_bwmode) {720720+ /* Increase PHY switch and AGC settling time721721+ * on turbo mode (ath5k_hw_commit_eeprom_settings722722+ * will override settling time if available) */723723+ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) {724724+725725+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,726726+ AR5K_PHY_SETTLING_AGC,727727+ AR5K_AGC_SETTLING_TURBO);728728+729729+ /* XXX: Initvals indicate we only increase730730+ * switch time on AR5212, 5211 and 5210731731+ * only change agc time (bug?) */732732+ if (ah->ah_version == AR5K_AR5212)733733+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,734734+ AR5K_PHY_SETTLING_SWITCH,735735+ AR5K_SWITCH_SETTLING_TURBO);736736+737737+ if (ah->ah_version == AR5K_AR5210) {738738+ /* Set Frame Control Register */739739+ ath5k_hw_reg_write(ah,740740+ (AR5K_PHY_FRAME_CTL_INI |741741+ AR5K_PHY_TURBO_MODE |742742+ AR5K_PHY_TURBO_SHORT | 0x2020),743743+ AR5K_PHY_FRAME_CTL_5210);744744+ }745745+ /* On 5413 PHY force window length for half/quarter rate*/746746+ } else if ((ah->ah_mac_srev >= AR5K_SREV_AR5424) &&747747+ (ah->ah_mac_srev <= AR5K_SREV_AR5414)) {748748+ AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL_5211,749749+ AR5K_PHY_FRAME_CTL_WIN_LEN,750750+ 3);751751+ }752752+ } else if (ah->ah_version == AR5K_AR5210) {753753+ /* Set Frame Control Register for normal operation */754754+ ath5k_hw_reg_write(ah, (AR5K_PHY_FRAME_CTL_INI | 0x1020),755755+ AR5K_PHY_FRAME_CTL_5210);837756 }838757}839758···870733{871734 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;872735 s16 cck_ofdm_pwr_delta;736736+737737+ /* TODO: Add support for AR5210 EEPROM */738738+ if (ah->ah_version == AR5K_AR5210)739739+ return;873740874741 /* Adjust power delta for channel 14 */875742 if (channel->center_freq == 2484)···913772 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),914773 AR5K_PHY_NFTHRES);915774916916- if ((channel->hw_value & CHANNEL_TURBO) &&775775+ if ((ah->ah_bwmode == AR5K_BWMODE_40MHZ) &&917776 (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {918777 /* Switch settling time (Turbo) */919778 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,···1011870 ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);1012871}101387210141014-/*10151015- * Main reset function10161016- */873873+874874+/*********************\875875+* Main reset function *876876+\*********************/877877+1017878int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,10181018- struct ieee80211_channel *channel, bool change_channel)879879+ struct ieee80211_channel *channel, bool fast, bool skip_pcu)1019880{10201020- struct ath_common *common = ath5k_hw_common(ah);10211021- u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo;10221022- u32 phy_tst1;881881+ u32 s_seq[10], s_led[3], tsf_up, tsf_lo;1023882 u8 mode, freq, ee_mode;1024883 int i, ret;10258841026885 ee_mode = 0;10271027- staid1_flags = 0;1028886 tsf_up = 0;1029887 tsf_lo = 0;1030888 freq = 0;1031889 mode = 0;10328901033891 /*10341034- * Save some registers before a reset892892+ * Sanity check for fast flag893893+ * Fast channel change only available894894+ * on AR2413/AR5413.1035895 */10361036- /*DCU/Antenna selection not available on 5210*/10371037- if (ah->ah_version != AR5K_AR5210) {896896+ if (fast && (ah->ah_radio != AR5K_RF2413) &&897897+ (ah->ah_radio != AR5K_RF5413))898898+ fast = 0;103889910391039- switch (channel->hw_value & CHANNEL_MODES) {10401040- case CHANNEL_A:10411041- mode = AR5K_MODE_11A;10421042- freq = AR5K_INI_RFGAIN_5GHZ;10431043- ee_mode = AR5K_EEPROM_MODE_11A;10441044- break;10451045- case CHANNEL_G:10461046- mode = AR5K_MODE_11G;10471047- freq = AR5K_INI_RFGAIN_2GHZ;10481048- ee_mode = AR5K_EEPROM_MODE_11G;10491049- break;10501050- case CHANNEL_B:10511051- mode = AR5K_MODE_11B;10521052- freq = AR5K_INI_RFGAIN_2GHZ;10531053- ee_mode = AR5K_EEPROM_MODE_11B;10541054- break;10551055- case CHANNEL_T:10561056- mode = AR5K_MODE_11A_TURBO;10571057- freq = AR5K_INI_RFGAIN_5GHZ;10581058- ee_mode = AR5K_EEPROM_MODE_11A;10591059- break;10601060- case CHANNEL_TG:10611061- if (ah->ah_version == AR5K_AR5211) {10621062- ATH5K_ERR(ah->ah_sc,10631063- "TurboG mode not available on 5211");10641064- return -EINVAL;10651065- }10661066- mode = AR5K_MODE_11G_TURBO;10671067- freq = AR5K_INI_RFGAIN_2GHZ;10681068- ee_mode = AR5K_EEPROM_MODE_11G;10691069- break;10701070- case CHANNEL_XR:10711071- if (ah->ah_version == AR5K_AR5211) {10721072- ATH5K_ERR(ah->ah_sc,10731073- "XR mode not available on 5211");10741074- return -EINVAL;10751075- }10761076- mode = AR5K_MODE_XR;10771077- freq = AR5K_INI_RFGAIN_5GHZ;10781078- ee_mode = AR5K_EEPROM_MODE_11A;10791079- break;10801080- default:900900+ /* Disable sleep clock operation901901+ * to avoid register access delay on certain902902+ * PHY registers */903903+ if (ah->ah_version == AR5K_AR5212)904904+ ath5k_hw_set_sleep_clock(ah, false);905905+906906+ /*907907+ * Stop PCU908908+ */909909+ ath5k_hw_stop_rx_pcu(ah);910910+911911+ /*912912+ * Stop DMA913913+ *914914+ * Note: If DMA didn't stop continue915915+ * since only a reset will fix it.916916+ */917917+ ret = ath5k_hw_dma_stop(ah);918918+919919+ /* RF Bus grant won't work if we have pending920920+ * frames */921921+ if (ret && fast) {922922+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,923923+ "DMA didn't stop, falling back to normal reset\n");924924+ fast = 0;925925+ /* Non fatal, just continue with926926+ * normal reset */927927+ ret = 0;928928+ }929929+930930+ switch (channel->hw_value & CHANNEL_MODES) {931931+ case CHANNEL_A:932932+ mode = AR5K_MODE_11A;933933+ freq = AR5K_INI_RFGAIN_5GHZ;934934+ ee_mode = AR5K_EEPROM_MODE_11A;935935+ break;936936+ case CHANNEL_G:937937+938938+ if (ah->ah_version <= AR5K_AR5211) {1081939 ATH5K_ERR(ah->ah_sc,10821082- "invalid channel: %d\n", channel->center_freq);940940+ "G mode not available on 5210/5211");1083941 return -EINVAL;1084942 }108594310861086- if (change_channel) {10871087- /*10881088- * Save frame sequence count10891089- * For revs. after Oahu, only save10901090- * seq num for DCU 0 (Global seq num)10911091- */10921092- if (ah->ah_mac_srev < AR5K_SREV_AR5211) {944944+ mode = AR5K_MODE_11G;945945+ freq = AR5K_INI_RFGAIN_2GHZ;946946+ ee_mode = AR5K_EEPROM_MODE_11G;947947+ break;948948+ case CHANNEL_B:109394910941094- for (i = 0; i < 10; i++)10951095- s_seq[i] = ath5k_hw_reg_read(ah,10961096- AR5K_QUEUE_DCU_SEQNUM(i));10971097-10981098- } else {10991099- s_seq[0] = ath5k_hw_reg_read(ah,11001100- AR5K_QUEUE_DCU_SEQNUM(0));11011101- }11021102-11031103- /* TSF accelerates on AR5211 during reset11041104- * As a workaround save it here and restore11051105- * it later so that it's back in time after11061106- * reset. This way it'll get re-synced on the11071107- * next beacon without breaking ad-hoc.11081108- *11091109- * On AR5212 TSF is almost preserved across a11101110- * reset so it stays back in time anyway and11111111- * we don't have to save/restore it.11121112- *11131113- * XXX: Since this breaks power saving we have11141114- * to disable power saving until we receive the11151115- * next beacon, so we can resync beacon timers */11161116- if (ah->ah_version == AR5K_AR5211) {11171117- tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);11181118- tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);11191119- }950950+ if (ah->ah_version < AR5K_AR5211) {951951+ ATH5K_ERR(ah->ah_sc,952952+ "B mode not available on 5210");953953+ return -EINVAL;1120954 }112195511221122- if (ah->ah_version == AR5K_AR5212) {11231123- /* Restore normal 32/40MHz clock operation11241124- * to avoid register access delay on certain11251125- * PHY registers */11261126- ath5k_hw_set_sleep_clock(ah, false);956956+ mode = AR5K_MODE_11B;957957+ freq = AR5K_INI_RFGAIN_2GHZ;958958+ ee_mode = AR5K_EEPROM_MODE_11B;959959+ break;960960+ case CHANNEL_XR:961961+ if (ah->ah_version == AR5K_AR5211) {962962+ ATH5K_ERR(ah->ah_sc,963963+ "XR mode not available on 5211");964964+ return -EINVAL;965965+ }966966+ mode = AR5K_MODE_XR;967967+ freq = AR5K_INI_RFGAIN_5GHZ;968968+ ee_mode = AR5K_EEPROM_MODE_11A;969969+ break;970970+ default:971971+ ATH5K_ERR(ah->ah_sc,972972+ "invalid channel: %d\n", channel->center_freq);973973+ return -EINVAL;974974+ }112797511281128- /* Since we are going to write rf buffer11291129- * check if we have any pending gain_F11301130- * optimization settings */11311131- if (change_channel && ah->ah_rf_banks != NULL)11321132- ath5k_hw_gainf_calibrate(ah);976976+ /*977977+ * If driver requested fast channel change and DMA has stopped978978+ * go on. If it fails continue with a normal reset.979979+ */980980+ if (fast) {981981+ ret = ath5k_hw_phy_init(ah, channel, mode,982982+ ee_mode, freq, true);983983+ if (ret) {984984+ ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,985985+ "fast chan change failed, falling back to normal reset\n");986986+ /* Non fatal, can happen eg.987987+ * on mode change */988988+ ret = 0;989989+ } else990990+ return 0;991991+ }992992+993993+ /*994994+ * Save some registers before a reset995995+ */996996+ if (ah->ah_version != AR5K_AR5210) {997997+ /*998998+ * Save frame sequence count999999+ * For revs. after Oahu, only save10001000+ * seq num for DCU 0 (Global seq num)10011001+ */10021002+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {10031003+10041004+ for (i = 0; i < 10; i++)10051005+ s_seq[i] = ath5k_hw_reg_read(ah,10061006+ AR5K_QUEUE_DCU_SEQNUM(i));10071007+10081008+ } else {10091009+ s_seq[0] = ath5k_hw_reg_read(ah,10101010+ AR5K_QUEUE_DCU_SEQNUM(0));10111011+ }10121012+10131013+ /* TSF accelerates on AR5211 during reset10141014+ * As a workaround save it here and restore10151015+ * it later so that it's back in time after10161016+ * reset. This way it'll get re-synced on the10171017+ * next beacon without breaking ad-hoc.10181018+ *10191019+ * On AR5212 TSF is almost preserved across a10201020+ * reset so it stays back in time anyway and10211021+ * we don't have to save/restore it.10221022+ *10231023+ * XXX: Since this breaks power saving we have10241024+ * to disable power saving until we receive the10251025+ * next beacon, so we can resync beacon timers */10261026+ if (ah->ah_version == AR5K_AR5211) {10271027+ tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);10281028+ tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);11331029 }11341030 }10311031+1135103211361033 /*GPIOs*/11371034 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &···1177998 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);1178999 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);1179100011801180- /* AR5K_STA_ID1 flags, only preserve antenna11811181- * settings and ack/cts rate mode */11821182- staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &11831183- (AR5K_STA_ID1_DEFAULT_ANTENNA |11841184- AR5K_STA_ID1_DESC_ANTENNA |11851185- AR5K_STA_ID1_RTS_DEF_ANTENNA |11861186- AR5K_STA_ID1_ACKCTS_6MB |11871187- AR5K_STA_ID1_BASE_RATE_11B |11881188- AR5K_STA_ID1_SELFGEN_DEF_ANT);10011001+10021002+ /*10031003+ * Since we are going to write rf buffer10041004+ * check if we have any pending gain_F10051005+ * optimization settings10061006+ */10071007+ if (ah->ah_version == AR5K_AR5212 &&10081008+ (ah->ah_radio <= AR5K_RF5112)) {10091009+ if (!fast && ah->ah_rf_banks != NULL)10101010+ ath5k_hw_gainf_calibrate(ah);10111011+ }1189101211901013 /* Wakeup the device */11911014 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);···12021021 AR5K_PHY(0));1203102212041023 /* Write initial settings */12051205- ret = ath5k_hw_write_initvals(ah, mode, change_channel);10241024+ ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);12061025 if (ret)12071026 return ret;1208102710281028+ /* Initialize core clock settings */10291029+ ath5k_hw_init_core_clock(ah);10301030+12091031 /*12101210- * 5211/5212 Specific10321032+ * Tweak initval settings for revised10331033+ * chipsets and add some more config10341034+ * bits12111035 */12121212- if (ah->ah_version != AR5K_AR5210) {10361036+ ath5k_hw_tweak_initval_settings(ah, channel);1213103712141214- /*12151215- * Write initial RF gain settings12161216- * This should work for both 5111/511212171217- */12181218- ret = ath5k_hw_rfgain_init(ah, freq);12191219- if (ret)12201220- return ret;10381038+ /* Commit values from EEPROM */10391039+ ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);1221104012221222- mdelay(1);12231223-12241224- /*12251225- * Tweak initval settings for revised12261226- * chipsets and add some more config12271227- * bits12281228- */12291229- ath5k_hw_tweak_initval_settings(ah, channel);12301230-12311231- /*12321232- * Set TX power12331233- */12341234- ret = ath5k_hw_txpower(ah, channel, ee_mode,12351235- ah->ah_txpower.txp_max_pwr / 2);12361236- if (ret)12371237- return ret;12381238-12391239- /* Write rate duration table only on AR5212 and if12401240- * virtual interface has already been brought up12411241- * XXX: rethink this after new mode changes to12421242- * mac80211 are integrated */12431243- if (ah->ah_version == AR5K_AR5212 &&12441244- ah->ah_sc->nvifs)12451245- ath5k_hw_write_rate_duration(ah, mode);12461246-12471247- /*12481248- * Write RF buffer12491249- */12501250- ret = ath5k_hw_rfregs_init(ah, channel, mode);12511251- if (ret)12521252- return ret;12531253-12541254-12551255- /* Write OFDM timings on 5212*/12561256- if (ah->ah_version == AR5K_AR5212 &&12571257- channel->hw_value & CHANNEL_OFDM) {12581258-12591259- ret = ath5k_hw_write_ofdm_timings(ah, channel);12601260- if (ret)12611261- return ret;12621262-12631263- /* Spur info is available only from EEPROM versions12641264- * greater than 5.3, but the EEPROM routines will use12651265- * static values for older versions */12661266- if (ah->ah_mac_srev >= AR5K_SREV_AR5424)12671267- ath5k_hw_set_spur_mitigation_filter(ah,12681268- channel);12691269- }12701270-12711271- /*Enable/disable 802.11b mode on 511112721272- (enable 2111 frequency converter + CCK)*/12731273- if (ah->ah_radio == AR5K_RF5111) {12741274- if (mode == AR5K_MODE_11B)12751275- AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,12761276- AR5K_TXCFG_B_MODE);12771277- else12781278- AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,12791279- AR5K_TXCFG_B_MODE);12801280- }12811281-12821282- /* Commit values from EEPROM */12831283- ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);12841284-12851285- } else {12861286- /*12871287- * For 5210 we do all initialization using12881288- * initvals, so we don't have to modify12891289- * any settings (5210 also only supports12901290- * a/aturbo modes)12911291- */12921292- mdelay(1);12931293- /* Disable phy and wait */12941294- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);12951295- mdelay(1);12961296- }1297104112981042 /*12991043 * Restore saved values13001044 */1301104513021302- /*DCU/Antenna selection not available on 5210*/10461046+ /* Seqnum, TSF */13031047 if (ah->ah_version != AR5K_AR5210) {10481048+ if (ah->ah_mac_srev < AR5K_SREV_AR5211) {10491049+ for (i = 0; i < 10; i++)10501050+ ath5k_hw_reg_write(ah, s_seq[i],10511051+ AR5K_QUEUE_DCU_SEQNUM(i));10521052+ } else {10531053+ ath5k_hw_reg_write(ah, s_seq[0],10541054+ AR5K_QUEUE_DCU_SEQNUM(0));10551055+ }1304105613051305- if (change_channel) {13061306- if (ah->ah_mac_srev < AR5K_SREV_AR5211) {13071307- for (i = 0; i < 10; i++)13081308- ath5k_hw_reg_write(ah, s_seq[i],13091309- AR5K_QUEUE_DCU_SEQNUM(i));13101310- } else {13111311- ath5k_hw_reg_write(ah, s_seq[0],13121312- AR5K_QUEUE_DCU_SEQNUM(0));13131313- }13141314-13151315-13161316- if (ah->ah_version == AR5K_AR5211) {13171317- ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);13181318- ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);13191319- }10571057+ if (ah->ah_version == AR5K_AR5211) {10581058+ ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);10591059+ ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);13201060 }13211061 }13221062···12481146 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);12491147 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);1250114812511251- /* Restore sta_id flags and preserve our mac address*/12521252- ath5k_hw_reg_write(ah,12531253- get_unaligned_le32(common->macaddr),12541254- AR5K_STA_ID0);12551255- ath5k_hw_reg_write(ah,12561256- staid1_flags | get_unaligned_le16(common->macaddr + 4),12571257- AR5K_STA_ID1);12581258-11491149+ /*11501150+ * Initialize PCU11511151+ */11521152+ ath5k_hw_pcu_init(ah, op_mode, mode);1259115312601154 /*12611261- * Configure PCU11551155+ * Initialize PHY12621156 */12631263-12641264- /* Restore bssid and bssid mask */12651265- ath5k_hw_set_bssid(ah);12661266-12671267- /* Set PCU config */12681268- ath5k_hw_set_opmode(ah, op_mode);12691269-12701270- /* Clear any pending interrupts12711271- * PISR/SISR Not available on 5210 */12721272- if (ah->ah_version != AR5K_AR5210)12731273- ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);12741274-12751275- /* Set RSSI/BRSSI thresholds12761276- *12771277- * Note: If we decide to set this value12781278- * dynamically, keep in mind that when AR5K_RSSI_THR12791279- * register is read, it might return 0x40 if we haven't12801280- * written anything to it. Also, BMISS RSSI threshold is zeroed.12811281- * So doing a save/restore procedure here isn't the right12821282- * choice. Instead, store it in ath5k_hw */12831283- ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |12841284- AR5K_TUNE_BMISS_THRES <<12851285- AR5K_RSSI_THR_BMISS_S),12861286- AR5K_RSSI_THR);12871287-12881288- /* MIC QoS support */12891289- if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {12901290- ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);12911291- ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);12921292- }12931293-12941294- /* QoS NOACK Policy */12951295- if (ah->ah_version == AR5K_AR5212) {12961296- ath5k_hw_reg_write(ah,12971297- AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |12981298- AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |12991299- AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),13001300- AR5K_QOS_NOACK);13011301- }13021302-13031303-13041304- /*13051305- * Configure PHY13061306- */13071307-13081308- /* Set channel on PHY */13091309- ret = ath5k_hw_channel(ah, channel);13101310- if (ret)11571157+ ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false);11581158+ if (ret) {11591159+ ATH5K_ERR(ah->ah_sc,11601160+ "failed to initialize PHY (%i) !\n", ret);13111161 return ret;13121312-13131313- /*13141314- * Enable the PHY and wait until completion13151315- * This includes BaseBand and Synthesizer13161316- * activation.13171317- */13181318- ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);13191319-13201320- /*13211321- * On 5211+ read activation -> rx delay13221322- * and use it.13231323- *13241324- * TODO: Half/quarter rate support13251325- */13261326- if (ah->ah_version != AR5K_AR5210) {13271327- u32 delay;13281328- delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &13291329- AR5K_PHY_RX_DELAY_M;13301330- delay = (channel->hw_value & CHANNEL_CCK) ?13311331- ((delay << 2) / 22) : (delay / 10);13321332-13331333- udelay(100 + (2 * delay));13341334- } else {13351335- mdelay(1);13361162 }13371337-13381338- /*13391339- * Perform ADC test to see if baseband is ready13401340- * Set TX hold and check ADC test register13411341- */13421342- phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);13431343- ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);13441344- for (i = 0; i <= 20; i++) {13451345- if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))13461346- break;13471347- udelay(200);13481348- }13491349- ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);13501350-13511351- /*13521352- * Start automatic gain control calibration13531353- *13541354- * During AGC calibration RX path is re-routed to13551355- * a power detector so we don't receive anything.13561356- *13571357- * This method is used to calibrate some static offsets13581358- * used together with on-the fly I/Q calibration (the13591359- * one performed via ath5k_hw_phy_calibrate), which doesn't13601360- * interrupt rx path.13611361- *13621362- * While rx path is re-routed to the power detector we also13631363- * start a noise floor calibration to measure the13641364- * card's noise floor (the noise we measure when we are not13651365- * transmitting or receiving anything).13661366- *13671367- * If we are in a noisy environment, AGC calibration may time13681368- * out and/or noise floor calibration might timeout.13691369- */13701370- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,13711371- AR5K_PHY_AGCCTL_CAL | AR5K_PHY_AGCCTL_NF);13721372-13731373- /* At the same time start I/Q calibration for QAM constellation13741374- * -no need for CCK- */13751375- ah->ah_calibration = false;13761376- if (!(mode == AR5K_MODE_11B)) {13771377- ah->ah_calibration = true;13781378- AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,13791379- AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);13801380- AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,13811381- AR5K_PHY_IQ_RUN);13821382- }13831383-13841384- /* Wait for gain calibration to finish (we check for I/Q calibration13851385- * during ath5k_phy_calibrate) */13861386- if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,13871387- AR5K_PHY_AGCCTL_CAL, 0, false)) {13881388- ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",13891389- channel->center_freq);13901390- }13911391-13921392- /* Restore antenna mode */13931393- ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);13941394-13951395- /* Restore slot time and ACK timeouts */13961396- if (ah->ah_coverage_class > 0)13971397- ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);1398116313991164 /*14001165 * Configure QCUs/DCUs14011166 */14021402-14031403- /* TODO: HW Compression support for data queues */14041404- /* TODO: Burst prefetch for data queues */14051405-14061406- /*14071407- * Reset queues and start beacon timers at the end of the reset routine14081408- * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping14091409- * Note: If we want we can assign multiple qcus on one dcu.14101410- */14111411- for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {14121412- ret = ath5k_hw_reset_tx_queue(ah, i);14131413- if (ret) {14141414- ATH5K_ERR(ah->ah_sc,14151415- "failed to reset TX queue #%d\n", i);14161416- return ret;14171417- }14181418- }11671167+ ret = ath5k_hw_init_queues(ah);11681168+ if (ret)11691169+ return ret;141911701420117114211172 /*14221422- * Configure DMA/Interrupts11731173+ * Initialize DMA/Interrupts14231174 */11751175+ ath5k_hw_dma_init(ah);1424117614251425- /*14261426- * Set Rx/Tx DMA Configuration14271427- *14281428- * Set standard DMA size (128). Note that14291429- * a DMA size of 512 causes rx overruns and tx errors14301430- * on pci-e cards (tested on 5424 but since rx overruns14311431- * also occur on 5416/5418 with madwifi we set 12814321432- * for all PCI-E cards to be safe).14331433- *14341434- * XXX: need to check 5210 for this14351435- * TODO: Check out tx triger level, it's always 64 on dumps but I14361436- * guess we can tweak it and see how it goes ;-)14371437- */14381438- if (ah->ah_version != AR5K_AR5210) {14391439- AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,14401440- AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);14411441- AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,14421442- AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);14431443- }14441444-14451445- /* Pre-enable interrupts on 5211/5212*/14461446- if (ah->ah_version != AR5K_AR5210)14471447- ath5k_hw_set_imr(ah, ah->ah_imr);1448117714491178 /* Enable 32KHz clock function for AR5212+ chips14501179 * Set clocks to 32KHz operation and use an
···3535 bool bt_hold_rx_clear;3636};37373838-static const u16 ath_subsysid_tbl[] = {3939- AR9280_COEX2WIRE_SUBSYSID,4040- AT9285_COEX3WIRE_SA_SUBSYSID,4141- AT9285_COEX3WIRE_DA_SUBSYSID4242-};4343-4444-/*4545- * Checks the subsystem id of the device to see if it4646- * supports btcoex4747- */4848-bool ath9k_hw_btcoex_supported(struct ath_hw *ah)4949-{5050- int i;5151-5252- if (!ah->hw_version.subsysid)5353- return false;5454-5555- for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)5656- if (ah->hw_version.subsysid == ath_subsysid_tbl[i])5757- return true;5858-5959- return false;6060-}61386239void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)6340{
···664664 DRIVER_REQUIRE_COPY_IV,665665 DRIVER_REQUIRE_L2PAD,666666 DRIVER_REQUIRE_TXSTATUS_FIFO,667667+ DRIVER_REQUIRE_TASKLET_CONTEXT,667668668669 /*669670 * Driver features
+6-3
drivers/net/wireless/rt2x00/rt2x00dev.c
···379379 * through a mac80211 library call (RTS/CTS) then we should not380380 * send the status report back.381381 */382382- if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))383383- ieee80211_tx_status(rt2x00dev->hw, entry->skb);384384- else382382+ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {383383+ if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))384384+ ieee80211_tx_status(rt2x00dev->hw, entry->skb);385385+ else386386+ ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);387387+ } else385388 dev_kfree_skb_any(entry->skb);386389387390 /*
···358358 * user space application). %NL80211_ATTR_FRAME is used to specify the359359 * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and360360 * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on361361- * which channel the frame is to be transmitted or was received. This362362- * channel has to be the current channel (remain-on-channel or the363363- * operational channel). When called, this operation returns a cookie364364- * (%NL80211_ATTR_COOKIE) that will be included with the TX status event365365- * pertaining to the TX request.361361+ * which channel the frame is to be transmitted or was received. If this362362+ * channel is not the current channel (remain-on-channel or the363363+ * operational channel) the device will switch to the given channel and364364+ * transmit the frame, optionally waiting for a response for the time365365+ * specified using %NL80211_ATTR_DURATION. When called, this operation366366+ * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the367367+ * TX status event pertaining to the TX request.368368+ * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this369369+ * command may be used with the corresponding cookie to cancel the wait370370+ * time if it is known that it is no longer necessary.366371 * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility.367372 * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame368373 * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies···497492498493 NL80211_CMD_SET_CHANNEL,499494 NL80211_CMD_SET_WDS_PEER,495495+496496+ NL80211_CMD_FRAME_WAIT_CANCEL,500497501498 /* add new commands above here */502499···835828 *836829 * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS837830 *831831+ * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be832832+ * transmitted on another channel when the channel given doesn't match833833+ * the current channel. If the current channel doesn't match and this834834+ * flag isn't set, the frame will be rejected. This is also used as an835835+ * nl80211 capability flag.836836+ *838837 * @NL80211_ATTR_MAX: highest attribute number currently defined839838 * @__NL80211_ATTR_AFTER_LAST: internal use840839 */···10141001 NL80211_ATTR_WIPHY_ANTENNA_RX,1015100210161003 NL80211_ATTR_MCAST_RATE,10041004+10051005+ NL80211_ATTR_OFFCHANNEL_TX_OK,1017100610181007 /* add attributes here, update the policy in nl80211.c */10191008
+4
include/linux/ssb/ssb.h
···5555 u8 tri5gl; /* 5.2GHz TX isolation */5656 u8 tri5g; /* 5.3GHz TX isolation */5757 u8 tri5gh; /* 5.8GHz TX isolation */5858+ u8 txpid2g[4]; /* 2GHz TX power index */5959+ u8 txpid5gl[4]; /* 4.9 - 5.1GHz TX power index */6060+ u8 txpid5g[4]; /* 5.1 - 5.5GHz TX power index */6161+ u8 txpid5gh[4]; /* 5.5 - ...GHz TX power index */5862 u8 rxpo2g; /* 2GHz RX power offset */5963 u8 rxpo5g; /* 5GHz RX power offset */6064 u8 rssisav2g; /* 2GHz RSSI params */
+40
include/linux/ssb/ssb_regs.h
···299299#define SSB_SPROM4_AGAIN2_SHIFT 0300300#define SSB_SPROM4_AGAIN3 0xFF00 /* Antenna 3 */301301#define SSB_SPROM4_AGAIN3_SHIFT 8302302+#define SSB_SPROM4_TXPID2G01 0x0062 /* TX Power Index 2GHz */303303+#define SSB_SPROM4_TXPID2G0 0x00FF304304+#define SSB_SPROM4_TXPID2G0_SHIFT 0305305+#define SSB_SPROM4_TXPID2G1 0xFF00306306+#define SSB_SPROM4_TXPID2G1_SHIFT 8307307+#define SSB_SPROM4_TXPID2G23 0x0064 /* TX Power Index 2GHz */308308+#define SSB_SPROM4_TXPID2G2 0x00FF309309+#define SSB_SPROM4_TXPID2G2_SHIFT 0310310+#define SSB_SPROM4_TXPID2G3 0xFF00311311+#define SSB_SPROM4_TXPID2G3_SHIFT 8312312+#define SSB_SPROM4_TXPID5G01 0x0066 /* TX Power Index 5GHz middle subband */313313+#define SSB_SPROM4_TXPID5G0 0x00FF314314+#define SSB_SPROM4_TXPID5G0_SHIFT 0315315+#define SSB_SPROM4_TXPID5G1 0xFF00316316+#define SSB_SPROM4_TXPID5G1_SHIFT 8317317+#define SSB_SPROM4_TXPID5G23 0x0068 /* TX Power Index 5GHz middle subband */318318+#define SSB_SPROM4_TXPID5G2 0x00FF319319+#define SSB_SPROM4_TXPID5G2_SHIFT 0320320+#define SSB_SPROM4_TXPID5G3 0xFF00321321+#define SSB_SPROM4_TXPID5G3_SHIFT 8322322+#define SSB_SPROM4_TXPID5GL01 0x006A /* TX Power Index 5GHz low subband */323323+#define SSB_SPROM4_TXPID5GL0 0x00FF324324+#define SSB_SPROM4_TXPID5GL0_SHIFT 0325325+#define SSB_SPROM4_TXPID5GL1 0xFF00326326+#define SSB_SPROM4_TXPID5GL1_SHIFT 8327327+#define SSB_SPROM4_TXPID5GL23 0x006C /* TX Power Index 5GHz low subband */328328+#define SSB_SPROM4_TXPID5GL2 0x00FF329329+#define SSB_SPROM4_TXPID5GL2_SHIFT 0330330+#define SSB_SPROM4_TXPID5GL3 0xFF00331331+#define SSB_SPROM4_TXPID5GL3_SHIFT 8332332+#define SSB_SPROM4_TXPID5GH01 0x006E /* TX Power Index 5GHz high subband */333333+#define SSB_SPROM4_TXPID5GH0 0x00FF334334+#define SSB_SPROM4_TXPID5GH0_SHIFT 0335335+#define SSB_SPROM4_TXPID5GH1 0xFF00336336+#define SSB_SPROM4_TXPID5GH1_SHIFT 8337337+#define SSB_SPROM4_TXPID5GH23 0x0070 /* TX Power Index 5GHz high subband */338338+#define SSB_SPROM4_TXPID5GH2 0x00FF339339+#define SSB_SPROM4_TXPID5GH2_SHIFT 0340340+#define SSB_SPROM4_TXPID5GH3 0xFF00341341+#define SSB_SPROM4_TXPID5GH3_SHIFT 8302342#define SSB_SPROM4_MAXP_BG 0x0080 /* Max Power BG in path 1 */303343#define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */304344#define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */
+8-8
include/net/bluetooth/hci.h
···11-/* 11+/*22 BlueZ - Bluetooth protocol stack for Linux33 Copyright (C) 2000-2001 Qualcomm Incorporated44···1212 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1313 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.1414 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY1515- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 1616- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1717- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1515+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES1616+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1717+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1818 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.19192020- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 2121- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 2020+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,2121+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS2222 SOFTWARE IS DISCLAIMED.2323*/2424···489489490490#define HCI_OP_WRITE_PG_TIMEOUT 0x0c18491491492492-#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a492492+#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a493493 #define SCAN_DISABLED 0x00494494 #define SCAN_INQUIRY 0x01495495 #define SCAN_PAGE 0x02···874874875875struct hci_command_hdr {876876 __le16 opcode; /* OCF & OGF */877877- __u8 plen;877877+ __u8 plen;878878} __packed;879879880880struct hci_event_hdr {
···11-/* 11+/*22 BlueZ - Bluetooth protocol stack for Linux33 Copyright (C) 2000-2001 Qualcomm Incorporated44 Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org>···1414 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1515 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.1616 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY1717- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 1818- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1919- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1717+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES1818+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1919+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF2020 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.21212222- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 2323- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 2222+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,2323+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS2424 SOFTWARE IS DISCLAIMED.2525*/2626···417417 return sub == pi->remote_tx_win;418418}419419420420-#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1421421-#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8422422-#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE)423423-#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE424424-#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START420420+#define __get_txseq(ctrl) (((ctrl) & L2CAP_CTRL_TXSEQ) >> 1)421421+#define __get_reqseq(ctrl) (((ctrl) & L2CAP_CTRL_REQSEQ) >> 8)422422+#define __is_iframe(ctrl) (!((ctrl) & L2CAP_CTRL_FRAME_TYPE))423423+#define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE)424424+#define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START)425425426426void l2cap_load(void);427427
+9-9
include/net/bluetooth/rfcomm.h
···11-/* 22- RFCOMM implementation for Linux Bluetooth stack (BlueZ).11+/*22+ RFCOMM implementation for Linux Bluetooth stack (BlueZ)33 Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>44 Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>55···1111 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1212 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.1313 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY1414- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 1515- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1616- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1414+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES1515+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1616+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1717 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.18181919- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 2020- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 1919+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,2020+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS2121 SOFTWARE IS DISCLAIMED.2222*/2323···105105struct rfcomm_hdr {106106 u8 addr;107107 u8 ctrl;108108- u8 len; // Actual size can be 2 bytes108108+ u8 len; /* Actual size can be 2 bytes */109109} __packed;110110111111struct rfcomm_cmd {···228228/* ---- RFCOMM SEND RPN ---- */229229int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,230230 u8 bit_rate, u8 data_bits, u8 stop_bits,231231- u8 parity, u8 flow_ctrl_settings, 231231+ u8 parity, u8 flow_ctrl_settings,232232 u8 xon_char, u8 xoff_char, u16 param_mask);233233234234/* ---- RFCOMM DLCs (channels) ---- */
+10-10
include/net/bluetooth/sco.h
···11-/* 11+/*22 BlueZ - Bluetooth protocol stack for Linux33 Copyright (C) 2000-2001 Qualcomm Incorporated44···1212 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1313 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.1414 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY1515- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 1616- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1717- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1515+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES1616+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1717+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1818 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.19192020- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 2121- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 2020+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,2121+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS2222 SOFTWARE IS DISCLAIMED.2323*/2424···5555struct sco_conn {5656 struct hci_conn *hcon;57575858- bdaddr_t *dst;5959- bdaddr_t *src;6060-5858+ bdaddr_t *dst;5959+ bdaddr_t *src;6060+6161 spinlock_t lock;6262- struct sock *sk;6262+ struct sock *sk;63636464 unsigned int mtu;6565};
+15-3
include/net/cfg80211.h
···11341134 * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation.11351135 * This allows the operation to be terminated prior to timeout based on11361136 * the duration value.11371137- * @mgmt_tx: Transmit a management frame11371137+ * @mgmt_tx: Transmit a management frame.11381138+ * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management11391139+ * frame on another channel11381140 *11391141 * @testmode_cmd: run a test mode command11401142 *···11541152 * @mgmt_frame_register: Notify driver that a management frame type was11551153 * registered. Note that this callback may not sleep, and cannot run11561154 * concurrently with itself.11551155+ *11561156+ * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device.11571157+ * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may11581158+ * reject TX/RX mask combinations they cannot support by returning -EINVAL11591159+ * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX).11601160+ *11611161+ * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).11571162 */11581163struct cfg80211_ops {11591164 int (*suspend)(struct wiphy *wiphy);···13001291 u64 cookie);1301129213021293 int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev,13031303- struct ieee80211_channel *chan,12941294+ struct ieee80211_channel *chan, bool offchan,13041295 enum nl80211_channel_type channel_type,13051305- bool channel_type_valid,12961296+ bool channel_type_valid, unsigned int wait,13061297 const u8 *buf, size_t len, u64 *cookie);12981298+ int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,12991299+ struct net_device *dev,13001300+ u64 cookie);1307130113081302 int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,13091303 bool enabled, int timeout);
+24-4
include/net/mac80211.h
···20552055 *20562056 * This function may not be called in IRQ context. Calls to this function20572057 * for a single hardware must be synchronized against each other. Calls20582058- * to this function and ieee80211_tx_status_irqsafe() may not be mixed20592059- * for a single hardware.20582058+ * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()20592059+ * may not be mixed for a single hardware.20602060 *20612061 * @hw: the hardware the frame was transmitted by20622062 * @skb: the frame that was transmitted, owned by mac80211 after this call···20652065 struct sk_buff *skb);2066206620672067/**20682068+ * ieee80211_tx_status_ni - transmit status callback (in process context)20692069+ *20702070+ * Like ieee80211_tx_status() but can be called in process context.20712071+ *20722072+ * Calls to this function, ieee80211_tx_status() and20732073+ * ieee80211_tx_status_irqsafe() may not be mixed20742074+ * for a single hardware.20752075+ *20762076+ * @hw: the hardware the frame was transmitted by20772077+ * @skb: the frame that was transmitted, owned by mac80211 after this call20782078+ */20792079+static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw,20802080+ struct sk_buff *skb)20812081+{20822082+ local_bh_disable();20832083+ ieee80211_tx_status(hw, skb);20842084+ local_bh_enable();20852085+}20862086+20872087+/**20682088 * ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback20692089 *20702090 * Like ieee80211_tx_status() but can be called in IRQ context20712091 * (internally defers to a tasklet.)20722092 *20732073- * Calls to this function and ieee80211_tx_status() may not be mixed for a20742074- * single hardware.20932093+ * Calls to this function, ieee80211_tx_status() and20942094+ * ieee80211_tx_status_ni() may not be mixed for a single hardware.20752095 *20762096 * @hw: the hardware the frame was transmitted by20772097 * @skb: the frame that was transmitted, owned by mac80211 after this call
···15511551 return ieee80211_wk_cancel_remain_on_channel(sdata, cookie);15521552}1553155315541554+static enum work_done_result15551555+ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb)15561556+{15571557+ /*15581558+ * Use the data embedded in the work struct for reporting15591559+ * here so if the driver mangled the SKB before dropping15601560+ * it (which is the only way we really should get here)15611561+ * then we don't report mangled data.15621562+ *15631563+ * If there was no wait time, then by the time we get here15641564+ * the driver will likely not have reported the status yet,15651565+ * so in that case userspace will have to deal with it.15661566+ */15671567+15681568+ if (wk->offchan_tx.wait && wk->offchan_tx.frame)15691569+ cfg80211_mgmt_tx_status(wk->sdata->dev,15701570+ (unsigned long) wk->offchan_tx.frame,15711571+ wk->ie, wk->ie_len, false, GFP_KERNEL);15721572+15731573+ return WORK_DONE_DESTROY;15741574+}15751575+15541576static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,15551555- struct ieee80211_channel *chan,15771577+ struct ieee80211_channel *chan, bool offchan,15561578 enum nl80211_channel_type channel_type,15571557- bool channel_type_valid,15791579+ bool channel_type_valid, unsigned int wait,15581580 const u8 *buf, size_t len, u64 *cookie)15591581{15601582 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);15611583 struct ieee80211_local *local = sdata->local;15621584 struct sk_buff *skb;15631585 struct sta_info *sta;15861586+ struct ieee80211_work *wk;15641587 const struct ieee80211_mgmt *mgmt = (void *)buf;15651588 u32 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |15661589 IEEE80211_TX_CTL_REQ_TX_STATUS;15901590+ bool is_offchan = false;1567159115681592 /* Check that we are on the requested channel for transmission */15691593 if (chan != local->tmp_channel &&15701594 chan != local->oper_channel)15711571- return -EBUSY;15951595+ is_offchan = true;15721596 if (channel_type_valid &&15731597 (channel_type != local->tmp_channel_type &&15741598 channel_type != local->_oper_channel_type))15991599+ is_offchan = true;16001600+16011601+ if (is_offchan && !offchan)15751602 return -EBUSY;1576160315771604 switch (sdata->vif.type) {···16321605 IEEE80211_SKB_CB(skb)->flags = flags;1633160616341607 skb->dev = sdata->dev;16351635- ieee80211_tx_skb(sdata, skb);1636160816371609 *cookie = (unsigned long) skb;16101610+16111611+ /*16121612+ * Can transmit right away if the channel was the16131613+ * right one and there's no wait involved... If a16141614+ * wait is involved, we might otherwise not be on16151615+ * the right channel for long enough!16161616+ */16171617+ if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) {16181618+ ieee80211_tx_skb(sdata, skb);16191619+ return 0;16201620+ }16211621+16221622+ wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL);16231623+ if (!wk) {16241624+ kfree_skb(skb);16251625+ return -ENOMEM;16261626+ }16271627+16281628+ wk->type = IEEE80211_WORK_OFFCHANNEL_TX;16291629+ wk->chan = chan;16301630+ wk->sdata = sdata;16311631+ wk->done = ieee80211_offchan_tx_done;16321632+ wk->offchan_tx.frame = skb;16331633+ wk->offchan_tx.wait = wait;16341634+ wk->ie_len = len;16351635+ memcpy(wk->ie, buf, len);16361636+16371637+ ieee80211_add_work(wk);16381638 return 0;16391639+}16401640+16411641+static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,16421642+ struct net_device *dev,16431643+ u64 cookie)16441644+{16451645+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);16461646+ struct ieee80211_local *local = sdata->local;16471647+ struct ieee80211_work *wk;16481648+ int ret = -ENOENT;16491649+16501650+ mutex_lock(&local->mtx);16511651+ list_for_each_entry(wk, &local->work_list, list) {16521652+ if (wk->sdata != sdata)16531653+ continue;16541654+16551655+ if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)16561656+ continue;16571657+16581658+ if (cookie != (unsigned long) wk->offchan_tx.frame)16591659+ continue;16601660+16611661+ wk->timeout = jiffies;16621662+16631663+ ieee80211_queue_work(&local->hw, &local->work_work);16641664+ ret = 0;16651665+ break;16661666+ }16671667+ mutex_unlock(&local->mtx);16681668+16691669+ return ret;16391670}1640167116411672static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,···17801695 .remain_on_channel = ieee80211_remain_on_channel,17811696 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,17821697 .mgmt_tx = ieee80211_mgmt_tx,16981698+ .mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,17831699 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,17841700 .mgmt_frame_register = ieee80211_mgmt_frame_register,17851701 .set_antenna = ieee80211_set_antenna,
···538538{539539 struct sk_buff *skb = tid_agg_rx->reorder_buf[index];540540541541+ lockdep_assert_held(&tid_agg_rx->reorder_lock);542542+541543 if (!skb)542544 goto no_frame;543545···558556 struct sk_buff_head *frames)559557{560558 int index;559559+560560+ lockdep_assert_held(&tid_agg_rx->reorder_lock);561561562562 while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {563563 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %···584580 struct sk_buff_head *frames)585581{586582 int index, j;583583+584584+ lockdep_assert_held(&tid_agg_rx->reorder_lock);587585588586 /* release the buffer until next missing frame */589587 index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) %···689683 int index;690684 bool ret = true;691685686686+ spin_lock(&tid_agg_rx->reorder_lock);687687+692688 buf_size = tid_agg_rx->buf_size;693689 head_seq_num = tid_agg_rx->head_seq_num;694690695695- spin_lock(&tid_agg_rx->reorder_lock);696691 /* frame with out of date sequence number */697692 if (seq_less(mpdu_seq_num, head_seq_num)) {698693 dev_kfree_skb(skb);···18771870 dev->stats.rx_packets++;18781871 dev->stats.rx_bytes += rx->skb->len;1879187218801880- if (ieee80211_is_data(hdr->frame_control) &&18811881- !is_multicast_ether_addr(hdr->addr1) &&18821882- local->hw.conf.dynamic_ps_timeout > 0 && local->ps_sdata) {18731873+ if (local->ps_sdata && local->hw.conf.dynamic_ps_timeout > 0 &&18741874+ !is_multicast_ether_addr(((struct ethhdr *)rx->skb->data)->h_dest)) {18831875 mod_timer(&local->dynamic_ps_timer, jiffies +18841876 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));18851877 }···19271921 mod_timer(&tid_agg_rx->session_timer,19281922 TU_TO_EXP_TIME(tid_agg_rx->timeout));1929192319241924+ spin_lock(&tid_agg_rx->reorder_lock);19301925 /* release stored frames up to start of BAR */19311926 ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num,19321927 frames);19281928+ spin_unlock(&tid_agg_rx->reorder_lock);19291929+19331930 kfree_skb(skb);19341931 return RX_QUEUED;19351932 }···22542245 break;22552246 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):22562247 case cpu_to_le16(IEEE80211_STYPE_DISASSOC):22482248+ if (is_multicast_ether_addr(mgmt->da) &&22492249+ !is_broadcast_ether_addr(mgmt->da))22502250+ return RX_DROP_MONITOR;22512251+22572252 /* process only for station */22582253 if (sdata->vif.type != NL80211_IFTYPE_STATION)22592254 return RX_DROP_MONITOR;···25282515}2529251625302517/*25312531- * This function makes calls into the RX path. Therefore the25322532- * caller must hold the sta_info->lock and everything has to25332533- * be under rcu_read_lock protection as well.25182518+ * This function makes calls into the RX path, therefore25192519+ * it has to be invoked under RCU read lock.25342520 */25352521void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)25362522{···2751273927522740 if (ieee80211_prepare_and_rx_handle(&rx, skb, true))27532741 return;27422742+ goto out;27542743 }27552744 }27562745···27912778 return;27922779 }2793278027812781+ out:27942782 dev_kfree_skb(skb);27952783}27962784
+14-15
net/mac80211/sta_info.h
···8181 * @stop_initiator: initiator of a session stop8282 * @tx_stop: TX DelBA frame when stopping8383 *8484- * This structure is protected by RCU and the per-station8585- * spinlock. Assignments to the array holding it must hold8686- * the spinlock, only the TX path can access it under RCU8787- * lock-free if, and only if, the state has the flag8888- * %HT_AGG_STATE_OPERATIONAL set. Otherwise, the TX path8989- * must also acquire the spinlock and re-check the state,9090- * see comments in the tx code touching it.8484+ * This structure's lifetime is managed by RCU, assignments to8585+ * the array holding it must hold the aggregation mutex.8686+ *8787+ * The TX path can access it under RCU lock-free if, and8888+ * only if, the state has the flag %HT_AGG_STATE_OPERATIONAL8989+ * set. Otherwise, the TX path must also acquire the spinlock9090+ * and re-check the state, see comments in the tx code9191+ * touching it.9192 */9293struct tid_ampdu_tx {9394 struct rcu_head rcu_head;···116115 * @rcu_head: RCU head used for freeing this struct117116 * @reorder_lock: serializes access to reorder buffer, see below.118117 *119119- * This structure is protected by RCU and the per-station120120- * spinlock. Assignments to the array holding it must hold121121- * the spinlock.118118+ * This structure's lifetime is managed by RCU, assignments to119119+ * the array holding it must hold the aggregation mutex.122120 *123123- * The @reorder_lock is used to protect the variables and124124- * arrays such as @reorder_buf, @reorder_time, @head_seq_num,125125- * @stored_mpdu_num and @reorder_time from being corrupted by126126- * concurrent access of the RX path and the expired frame127127- * release timer.121121+ * The @reorder_lock is used to protect the members of this122122+ * struct, except for @timeout, @buf_size and @dialog_token,123123+ * which are constant across the lifetime of the struct (the124124+ * dialog token being used only for debugging).128125 */129126struct tid_ampdu_rx {130127 struct rcu_head rcu_head;
+14-1
net/mac80211/status.c
···321321 msecs_to_jiffies(10));322322 }323323324324- if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX)324324+ if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) {325325+ struct ieee80211_work *wk;326326+327327+ rcu_read_lock();328328+ list_for_each_entry_rcu(wk, &local->work_list, list) {329329+ if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX)330330+ continue;331331+ if (wk->offchan_tx.frame != skb)332332+ continue;333333+ wk->offchan_tx.frame = NULL;334334+ break;335335+ }336336+ rcu_read_unlock();325337 cfg80211_mgmt_tx_status(326338 skb->dev, (unsigned long) skb, skb->data, skb->len,327339 !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);340340+ }328341329342 /* this was a transmitted frame, but now we want to reuse it */330343 skb_orphan(skb);
+6-1
net/mac80211/tx.c
···15951595 list) {15961596 if (!ieee80211_sdata_running(tmp_sdata))15971597 continue;15981598- if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)15981598+ if (tmp_sdata->vif.type ==15991599+ NL80211_IFTYPE_MONITOR ||16001600+ tmp_sdata->vif.type ==16011601+ NL80211_IFTYPE_AP_VLAN ||16021602+ tmp_sdata->vif.type ==16031603+ NL80211_IFTYPE_WDS)15991604 continue;16001605 if (compare_ether_addr(tmp_sdata->vif.addr,16011606 hdr->addr2) == 0) {
+22
net/mac80211/work.c
···561561}562562563563static enum work_action __must_check564564+ieee80211_offchannel_tx(struct ieee80211_work *wk)565565+{566566+ if (!wk->started) {567567+ wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait);568568+569569+ /*570570+ * After this, offchan_tx.frame remains but now is no571571+ * longer a valid pointer -- we still need it as the572572+ * cookie for canceling this work.573573+ */574574+ ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);575575+576576+ return WORK_ACT_NONE;577577+ }578578+579579+ return WORK_ACT_TIMEOUT;580580+}581581+582582+static enum work_action __must_check564583ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)565584{566585 if (wk->started)···973954 break;974955 case IEEE80211_WORK_REMAIN_ON_CHANNEL:975956 rma = ieee80211_remain_on_channel_timeout(wk);957957+ break;958958+ case IEEE80211_WORK_OFFCHANNEL_TX:959959+ rma = ieee80211_offchannel_tx(wk);976960 break;977961 case IEEE80211_WORK_ASSOC_BEACON_WAIT:978962 rma = ieee80211_assoc_beacon_wait(wk);