On Tue, Dec 7, 2010 at 4:59 PM, John W. Linville <linville@xxxxxxxxxxxxx> wrote: > On Tue, Dec 07, 2010 at 04:57:08PM +0100, Sedat Dilek wrote: >> On Tue, Dec 7, 2010 at 3:26 PM, John W. Linville <linville@xxxxxxxxxxxxx> wrote: >> > On Tue, Dec 07, 2010 at 12:24:14PM +0100, Sedat Dilek wrote: >> > >> >> I have already reported on linux-wireless (short: l-w) ML that after >> >> especially the merge of "AHB Bus support" patchset (see [2]) my ath5k >> >> was not working as expected in daily use (also modinfo). >> >> >> >> I am not sure if it is the driver but reverting the 9 commits in my >> >> local linux-next GIT seemed to "stabilize" a bit the Internet >> >> connection. >> >> The patchset from Nick (see below) definitely helped to stabilize ath5k. >> > >> > I imagine that these are the "9 commits" you mean: >> > >> >> git rev-list c30ae13..4cebb34 >> > 4cebb34caa5122216a1e2451eae9e0fc47ec2589 >> > a0b907ee2a71052fefdf6151764095f3f97b3275 >> > c31b5c9c806b1fbdc9e98885d897664a0d482989 >> > e7aecd327d80b2f156b54769013aaccb2a20645a >> > 8efa5d7d6ad307ae2d220def37ca89594062c40d >> > 4aa5d783c9e1c72e4950ff34f388077ccecac74a >> > e5b046d86fac609f636d127a38de94a175c7e83b >> > 132b1c3ee38ea6fa0501004fd0f19acb554e5a44 >> > aeae4ac9090462ea38387dcdbac4f01b944af6a4 >> > >> > Most of those look fairly harmless so long as you don't define >> > CONFIG_ATHEROS_AR231X. ÂJust to narrow things down...if you only revert >> > the first 8 (i.e. leave aeae4ac alone), do you still have problems? >> > Or does it still "stabilize"? >> > >> > That patch converts the driver to the generic DMA API. ÂIt seems >> > OK at first glance, but I suspect it is the only one likely to be >> > effecting your situation. >> > >> > John >> > -- >> > John W. Linville        ÂSomeday the world will need a hero, and you >> > linville@xxxxxxxxxxxxx         Âmight be all we have. ÂBe ready. >> > >> >> Before jumping to another problem, I had a quick look into the >> appropriate Kconfig file, as you say I have not CONFIG_ATHEROS_AR231X >> set and that's why AHB support is not selected/built, instead >> >>  CC [M] Âdrivers/net/wireless/ath/ath5k/pci.o >> >> is built. >> >> Unfortunately, I can't cleanly revert. Sorry, I can't help. > > I don't quite understand -- you said you were reverting them before, > but now I ask you to revert one _less_ patch (i.e. the last one to > be reverted anyway) and you can't do it? > > John > -- > John W. Linville        ÂSomeday the world will need a hero, and you > linville@xxxxxxxxxxxxx         Âmight be all we have. ÂBe ready. > I tested with a linux-next (next-20101206) with revert-at5k-patches. Unfortunately, Nick's patchset is needed for a stable WLAN connection, several ReAssoc's etc. So, I can't give a comment to the effects of the AHB patchset on my AR5212. But... I have found the culprit patch which makes modinfo no more list the aliases/pci-id (see [1]): commit e5b046d86fac609f636d127a38de94a175c7e83b "ath5k: Move PCI bus functions to separate file." - Sedat - [1] http://git.kernel.org/?p=linux/kernel/git/linville/wireless-next-2.6.git;a=commit;h=e5b046d86fac609f636d127a38de94a175c7e83b $ ~/src/linux-2.6/linux-2.6.37-rc4/debian/build/source_i386_none $ cat .pc/applied-patches revert-ath5k-patches/0001-Revert-ath5k-Fix-reset-and-interrupts-for-AHB-type-o.patch revert-ath5k-patches/0002-Revert-ath5k-Add-AHB-bus-support.patch revert-ath5k-patches/0003-Revert-ath5k-Add-initial-registers-values-for-radio-.patch revert-ath5k-patches/0004-Revert-ath5k-Add-a-function-to-read-chipset-s-MAC-re.patch revert-ath5k-patches/0005-Revert-ath5k-Check-if-pci-pdev-struct-is-initialized.patch revert-ath5k-patches/0006-Revert-ath5k-Use-generic-eeprom-read-from-common-ath.patch revert-ath5k-patches/0007-Revert-ath5k-Move-PCI-bus-functions-to-separate-file.patch # modinfo ath5k filename: /lib/modules/2.6.37-rc4-686/kernel/drivers/net/wireless/ath/ath5k/ath5k.ko version: 0.6.0 (EXPERIMENTAL) license: Dual BSD/GPL description: Support for 5xxx series of Atheros 802.11 wireless LAN cards. author: Nick Kossifidis author: Jiri Slaby srcversion: 666105BAEE881F2C2F10CE6 alias: pci:v0000168Cd0000001Dsv*sd*bc*sc*i* alias: pci:v0000168Cd0000001Csv*sd*bc*sc*i* alias: pci:v0000168Cd0000001Bsv*sd*bc*sc*i* alias: pci:v0000168Cd0000001Asv*sd*bc*sc*i* alias: pci:v0000168Cd00000019sv*sd*bc*sc*i* alias: pci:v0000168Cd00000018sv*sd*bc*sc*i* alias: pci:v0000168Cd00000017sv*sd*bc*sc*i* alias: pci:v0000168Cd00000016sv*sd*bc*sc*i* alias: pci:v0000168Cd00000015sv*sd*bc*sc*i* alias: pci:v0000168Cd00000014sv*sd*bc*sc*i* alias: pci:v0000168Cd00001014sv*sd*bc*sc*i* alias: pci:v000010B7d00000013sv*sd*bc*sc*i* alias: pci:v0000A727d00000013sv*sd*bc*sc*i* alias: pci:v0000168Cd00000013sv*sd*bc*sc*i* alias: pci:v0000168Cd00000012sv*sd*bc*sc*i* alias: pci:v0000168Cd00000011sv*sd*bc*sc*i* alias: pci:v0000168Cd00000007sv*sd*bc*sc*i* alias: pci:v0000168Cd00000207sv*sd*bc*sc*i* depends: mac80211,cfg80211,ath vermagic: 2.6.37-rc4-686 SMP mod_unload modversions 686 parm: debug:uint parm: nohwcrypt:Disable hardware encryption. (bool) parm: all_channels:Expose all channels the device can use. (bool)
From e2f79441224cf9cd1f9e399ca774040f1ece72fa Mon Sep 17 00:00:00 2001 From: Sedat Dilek <sedat.dilek@xxxxxxxxx> Date: Fri, 3 Dec 2010 23:19:54 +0100 Subject: [PATCH 7/9] Revert "ath5k: Move PCI bus functions to separate file." This reverts commit e5b046d86fac609f636d127a38de94a175c7e83b. --- drivers/net/wireless/ath/ath5k/Makefile | 1 - drivers/net/wireless/ath/ath5k/ath5k.h | 3 - drivers/net/wireless/ath/ath5k/base.c | 267 +++++++++++++++++++++++++++++- drivers/net/wireless/ath/ath5k/pci.c | 284 ------------------------------- 4 files changed, 266 insertions(+), 289 deletions(-) delete mode 100644 drivers/net/wireless/ath/ath5k/pci.c diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index dae881c..2242a14 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile @@ -15,5 +15,4 @@ ath5k-y += rfkill.o ath5k-y += ani.o ath5k-y += sysfs.o ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o -ath5k-y += pci.o obj-$(CONFIG_ATH5K) += ath5k.o diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ee3c0af..a74f448 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -1145,7 +1145,6 @@ struct ath5k_hw { /* * Prototypes */ -extern const struct ieee80211_ops ath5k_hw_ops; /* Initialization and detach functions */ int ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops); @@ -1156,8 +1155,6 @@ void ath5k_hw_deinit(struct ath5k_hw *ah); int ath5k_sysfs_register(struct ath5k_softc *sc); void ath5k_sysfs_unregister(struct ath5k_softc *sc); -/*Chip id helper function */ -const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); /* LED functions */ int ath5k_init_leds(struct ath5k_softc *sc); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9fcc4e1..b11ea3d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -47,6 +47,8 @@ #include <linux/io.h> #include <linux/netdevice.h> #include <linux/cache.h> +#include <linux/pci.h> +#include <linux/pci-aspm.h> #include <linux/ethtool.h> #include <linux/uaccess.h> #include <linux/slab.h> @@ -85,6 +87,30 @@ static int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); +/* Known PCI ids */ +static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { + { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ + { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ + { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ + { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */ + { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */ + { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ + { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ + { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ + { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */ + { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ + { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ + { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ + { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); + /* Known SREVs */ static const struct ath5k_srev_name srev_names[] = { { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, @@ -167,6 +193,32 @@ static const struct ieee80211_rate ath5k_rates[] = { /* XR missing */ }; +/* return bus cachesize in 4B word units */ +static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) +{ + struct ath5k_softc *sc = (struct ath5k_softc *) common->priv; + u8 u8tmp; + + pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); + *csz = (int)u8tmp; + + /* + * This check was put in to avoid "unplesant" consequences if + * the bootrom has not fully initialized all PCI devices. + * Sometimes the cache line size register is not set + */ + + if (*csz == 0) + *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ +} + +/* Common ath_bus_opts structure */ +static const struct ath_bus_ops ath_pci_bus_ops = { + .ath_bus_type = ATH_PCI, + .read_cachesize = ath5k_pci_read_cachesize, +}; + + static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { @@ -209,7 +261,7 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) return (tsf & ~0x7fff) | rstamp; } -const char * +static const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) { const char *name = "xxxxx"; @@ -3575,3 +3627,216 @@ const struct ieee80211_ops ath5k_hw_ops = { .set_antenna = ath5k_set_antenna, .get_antenna = ath5k_get_antenna, }; + +/********************\ +* PCI Initialization * +\********************/ + +static int __devinit +ath5k_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + void __iomem *mem; + struct ath5k_softc *sc; + struct ieee80211_hw *hw; + int ret; + u8 csz; + + /* + * L0s needs to be disabled on all ath5k cards. + * + * For distributions shipping with CONFIG_PCIEASPM (this will be enabled + * by default in the future in 2.6.36) this will also mean both L1 and + * L0s will be disabled when a pre 1.1 PCIe device is detected. We do + * know L1 works correctly even for all ath5k pre 1.1 PCIe devices + * though but cannot currently undue the effect of a blacklist, for + * details you can read pcie_aspm_sanity_check() and see how it adjusts + * the device link capability. + * + * It may be possible in the future to implement some PCI API to allow + * drivers to override blacklists for pre 1.1 PCIe but for now it is + * best to accept that both L0s and L1 will be disabled completely for + * distributions shipping with CONFIG_PCIEASPM rather than having this + * issue present. Motivation for adding this new API will be to help + * with power consumption for some of these devices. + */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "can't enable device\n"); + goto err; + } + + /* XXX 32-bit addressing only */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "32-bit DMA not available\n"); + goto err_dis; + } + + /* + * Cache line size is used to size and align various + * structures used to communicate with the hardware. + */ + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); + if (csz == 0) { + /* + * Linux 2.4.18 (at least) writes the cache line size + * register as a 16-bit wide register which is wrong. + * We must have this setup properly for rx buffer + * DMA to work so force a reasonable value here if it + * comes up zero. + */ + csz = L1_CACHE_BYTES >> 2; + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); + } + /* + * The default setting of latency timer yields poor results, + * set it to the value used by other systems. It may be worth + * tweaking this setting more. + */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); + + /* Enable bus mastering */ + pci_set_master(pdev); + + /* + * Disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, 0x41, 0); + + ret = pci_request_region(pdev, 0, "ath5k"); + if (ret) { + dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); + goto err_dis; + } + + mem = pci_iomap(pdev, 0, 0); + if (!mem) { + dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; + ret = -EIO; + goto err_reg; + } + + /* + * Allocate hw (mac80211 main struct) + * and hw->priv (driver private data) + */ + hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); + if (hw == NULL) { + dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); + ret = -ENOMEM; + goto err_map; + } + + dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); + + sc = hw->priv; + sc->hw = hw; + sc->pdev = pdev; + sc->dev = &pdev->dev; + sc->irq = pdev->irq; + sc->devid = id->device; + sc->iobase = mem; /* So we can unmap it on detach */ + + /* Initialize */ + ret = ath5k_init_softc(sc, &ath_pci_bus_ops); + if (ret) { + goto err_free; + } + + /* Set private data */ + pci_set_drvdata(pdev, hw); + + return 0; +err_free: + ieee80211_free_hw(hw); +err_map: + pci_iounmap(pdev, mem); +err_reg: + pci_release_region(pdev, 0); +err_dis: + pci_disable_device(pdev); +err: + return ret; +} + +static void __devexit +ath5k_pci_remove(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct ath5k_softc *sc = hw->priv; + + ath5k_deinit_softc(sc); + pci_iounmap(pdev, sc->iobase); + pci_release_region(pdev, 0); + pci_disable_device(pdev); + ieee80211_free_hw(hw); +} + +#ifdef CONFIG_PM_SLEEP +static int ath5k_pci_suspend(struct device *dev) +{ + struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); + + ath5k_led_off(sc); + return 0; +} + +static int ath5k_pci_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ath5k_softc *sc = pci_get_drvdata(pdev); + + /* + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state + */ + pci_write_config_byte(pdev, 0x41, 0); + + ath5k_led_enable(sc); + return 0; +} + +static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); +#define ATH5K_PM_OPS (&ath5k_pm_ops) +#else +#define ATH5K_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +static struct pci_driver ath5k_pci_driver = { + .name = KBUILD_MODNAME, + .id_table = ath5k_pci_id_table, + .probe = ath5k_pci_probe, + .remove = __devexit_p(ath5k_pci_remove), + .driver.pm = ATH5K_PM_OPS, +}; + +/* + * Module init/exit functions + */ +static int __init +init_ath5k_pci(void) +{ + int ret; + + ret = pci_register_driver(&ath5k_pci_driver); + if (ret) { + printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); + return ret; + } + + return 0; +} + +static void __exit +exit_ath5k_pci(void) +{ + pci_unregister_driver(&ath5k_pci_driver); +} + +module_init(init_ath5k_pci); +module_exit(exit_ath5k_pci); diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c deleted file mode 100644 index 9f7d3ca..0000000 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2008-2009 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <linux/nl80211.h> -#include <linux/pci.h> -#include <linux/pci-aspm.h> -#include "../ath.h" -#include "ath5k.h" -#include "debug.h" -#include "base.h" -#include "reg.h" - -/* Known PCI ids */ -static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { - { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ - { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ - { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ - { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */ - { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */ - { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ - { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ - { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ - { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */ - { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ - { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ - { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ - { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ - { 0 } -}; - -/* return bus cachesize in 4B word units */ -static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz) -{ - struct ath5k_softc *sc = (struct ath5k_softc *) common->priv; - u8 u8tmp; - - pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp); - *csz = (int)u8tmp; - - /* - * This check was put in to avoid "unplesant" consequences if - * the bootrom has not fully initialized all PCI devices. - * Sometimes the cache line size register is not set - */ - - if (*csz == 0) - *csz = L1_CACHE_BYTES >> 2; /* Use the default size */ -} - -/* Common ath_bus_opts structure */ -static const struct ath_bus_ops ath_pci_bus_ops = { - .ath_bus_type = ATH_PCI, - .read_cachesize = ath5k_pci_read_cachesize, -}; - -/********************\ -* PCI Initialization * -\********************/ - -static int __devinit -ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - void __iomem *mem; - struct ath5k_softc *sc; - struct ieee80211_hw *hw; - int ret; - u8 csz; - - /* - * L0s needs to be disabled on all ath5k cards. - * - * For distributions shipping with CONFIG_PCIEASPM (this will be enabled - * by default in the future in 2.6.36) this will also mean both L1 and - * L0s will be disabled when a pre 1.1 PCIe device is detected. We do - * know L1 works correctly even for all ath5k pre 1.1 PCIe devices - * though but cannot currently undue the effect of a blacklist, for - * details you can read pcie_aspm_sanity_check() and see how it adjusts - * the device link capability. - * - * It may be possible in the future to implement some PCI API to allow - * drivers to override blacklists for pre 1.1 PCIe but for now it is - * best to accept that both L0s and L1 will be disabled completely for - * distributions shipping with CONFIG_PCIEASPM rather than having this - * issue present. Motivation for adding this new API will be to help - * with power consumption for some of these devices. - */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); - - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "can't enable device\n"); - goto err; - } - - /* XXX 32-bit addressing only */ - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "32-bit DMA not available\n"); - goto err_dis; - } - - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); - if (csz == 0) { - /* - * Linux 2.4.18 (at least) writes the cache line size - * register as a 16-bit wide register which is wrong. - * We must have this setup properly for rx buffer - * DMA to work so force a reasonable value here if it - * comes up zero. - */ - csz = L1_CACHE_BYTES >> 2; - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); - } - /* - * The default setting of latency timer yields poor results, - * set it to the value used by other systems. It may be worth - * tweaking this setting more. - */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); - - /* Enable bus mastering */ - pci_set_master(pdev); - - /* - * Disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, 0x41, 0); - - ret = pci_request_region(pdev, 0, "ath5k"); - if (ret) { - dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); - goto err_dis; - } - - mem = pci_iomap(pdev, 0, 0); - if (!mem) { - dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; - ret = -EIO; - goto err_reg; - } - - /* - * Allocate hw (mac80211 main struct) - * and hw->priv (driver private data) - */ - hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); - if (hw == NULL) { - dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); - ret = -ENOMEM; - goto err_map; - } - - dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); - - sc = hw->priv; - sc->hw = hw; - sc->pdev = pdev; - sc->dev = &pdev->dev; - sc->irq = pdev->irq; - sc->devid = id->device; - sc->iobase = mem; /* So we can unmap it on detach */ - - /* Initialize */ - ret = ath5k_init_softc(sc, &ath_pci_bus_ops); - if (ret) - goto err_free; - - /* Set private data */ - pci_set_drvdata(pdev, hw); - - return 0; -err_free: - ieee80211_free_hw(hw); -err_map: - pci_iounmap(pdev, mem); -err_reg: - pci_release_region(pdev, 0); -err_dis: - pci_disable_device(pdev); -err: - return ret; -} - -static void __devexit -ath5k_pci_remove(struct pci_dev *pdev) -{ - struct ieee80211_hw *hw = pci_get_drvdata(pdev); - struct ath5k_softc *sc = hw->priv; - - ath5k_deinit_softc(sc); - pci_iounmap(pdev, sc->iobase); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - ieee80211_free_hw(hw); -} - -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev) -{ - struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); - - ath5k_led_off(sc); - return 0; -} - -static int ath5k_pci_resume(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct ath5k_softc *sc = pci_get_drvdata(pdev); - - /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state - */ - pci_write_config_byte(pdev, 0x41, 0); - - ath5k_led_enable(sc); - return 0; -} - -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); -#define ATH5K_PM_OPS (&ath5k_pm_ops) -#else -#define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ - -static struct pci_driver ath5k_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = ath5k_pci_id_table, - .probe = ath5k_pci_probe, - .remove = __devexit_p(ath5k_pci_remove), - .driver.pm = ATH5K_PM_OPS, -}; - -/* - * Module init/exit functions - */ -static int __init -init_ath5k_pci(void) -{ - int ret; - - ret = pci_register_driver(&ath5k_pci_driver); - if (ret) { - printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); - return ret; - } - - return 0; -} - -static void __exit -exit_ath5k_pci(void) -{ - pci_unregister_driver(&ath5k_pci_driver); -} - -module_init(init_ath5k_pci); -module_exit(exit_ath5k_pci); -- 1.7.2.3