linux/drivers/net/wireless/ath/ath5k/pci.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2008-2009 Atheros Communications Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  18
  19#include <linux/nl80211.h>
  20#include <linux/pci.h>
  21#include <linux/pci-aspm.h>
  22#include <linux/etherdevice.h>
  23#include <linux/module.h>
  24#include "../ath.h"
  25#include "ath5k.h"
  26#include "debug.h"
  27#include "base.h"
  28#include "reg.h"
  29
  30/* Known PCI ids */
  31static const struct pci_device_id ath5k_pci_id_table[] = {
  32        { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
  33        { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
  34        { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
  35        { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
  36        { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
  37        { PCI_VDEVICE(3COM_2,  0x0013) }, /* 3com 5212 */
  38        { PCI_VDEVICE(3COM,    0x0013) }, /* 3com 3CRDAG675 5212 */
  39        { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
  40        { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 compatible */
  41        { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 compatible */
  42        { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 compatible */
  43        { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 compatible */
  44        { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 compatible */
  45        { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 compatible */
  46        { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
  47        { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
  48        { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
  49        { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
  50        { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
  51        { 0 }
  52};
  53MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
  54
  55/* return bus cachesize in 4B word units */
  56static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
  57{
  58        struct ath5k_hw *ah = (struct ath5k_hw *) common->priv;
  59        u8 u8tmp;
  60
  61        pci_read_config_byte(ah->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
  62        *csz = (int)u8tmp;
  63
  64        /*
  65         * This check was put in to avoid "unpleasant" consequences if
  66         * the bootrom has not fully initialized all PCI devices.
  67         * Sometimes the cache line size register is not set
  68         */
  69
  70        if (*csz == 0)
  71                *csz = L1_CACHE_BYTES >> 2;   /* Use the default size */
  72}
  73
  74/*
  75 * Read from eeprom
  76 */
  77static bool
  78ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
  79{
  80        struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
  81        u32 status, timeout;
  82
  83        /*
  84         * Initialize EEPROM access
  85         */
  86        if (ah->ah_version == AR5K_AR5210) {
  87                AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
  88                (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
  89        } else {
  90                ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
  91                AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
  92                                AR5K_EEPROM_CMD_READ);
  93        }
  94
  95        for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
  96                status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
  97                if (status & AR5K_EEPROM_STAT_RDDONE) {
  98                        if (status & AR5K_EEPROM_STAT_RDERR)
  99                                return false;
 100                        *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
 101                                        0xffff);
 102                        return true;
 103                }
 104                usleep_range(15, 20);
 105        }
 106
 107        return false;
 108}
 109
 110int ath5k_hw_read_srev(struct ath5k_hw *ah)
 111{
 112        ah->ah_mac_srev = ath5k_hw_reg_read(ah, AR5K_SREV);
 113        return 0;
 114}
 115
 116/*
 117 * Read the MAC address from eeprom or platform_data
 118 */
 119static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
 120{
 121        u8 mac_d[ETH_ALEN] = {};
 122        u32 total, offset;
 123        u16 data;
 124        int octet;
 125
 126        AR5K_EEPROM_READ(0x20, data);
 127
 128        for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
 129                AR5K_EEPROM_READ(offset, data);
 130
 131                total += data;
 132                mac_d[octet + 1] = data & 0xff;
 133                mac_d[octet] = data >> 8;
 134                octet += 2;
 135        }
 136
 137        if (!total || total == 3 * 0xffff)
 138                return -EINVAL;
 139
 140        memcpy(mac, mac_d, ETH_ALEN);
 141
 142        return 0;
 143}
 144
 145
 146/* Common ath_bus_opts structure */
 147static const struct ath_bus_ops ath_pci_bus_ops = {
 148        .ath_bus_type = ATH_PCI,
 149        .read_cachesize = ath5k_pci_read_cachesize,
 150        .eeprom_read = ath5k_pci_eeprom_read,
 151        .eeprom_read_mac = ath5k_pci_eeprom_read_mac,
 152};
 153
 154/********************\
 155* PCI Initialization *
 156\********************/
 157
 158static int
 159ath5k_pci_probe(struct pci_dev *pdev,
 160                const struct pci_device_id *id)
 161{
 162        void __iomem *mem;
 163        struct ath5k_hw *ah;
 164        struct ieee80211_hw *hw;
 165        int ret;
 166        u8 csz;
 167
 168        /*
 169         * L0s needs to be disabled on all ath5k cards.
 170         *
 171         * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
 172         * by default in the future in 2.6.36) this will also mean both L1 and
 173         * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
 174         * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
 175         * though but cannot currently undue the effect of a blacklist, for
 176         * details you can read pcie_aspm_sanity_check() and see how it adjusts
 177         * the device link capability.
 178         *
 179         * It may be possible in the future to implement some PCI API to allow
 180         * drivers to override blacklists for pre 1.1 PCIe but for now it is
 181         * best to accept that both L0s and L1 will be disabled completely for
 182         * distributions shipping with CONFIG_PCIEASPM rather than having this
 183         * issue present. Motivation for adding this new API will be to help
 184         * with power consumption for some of these devices.
 185         */
 186        pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
 187
 188        ret = pci_enable_device(pdev);
 189        if (ret) {
 190                dev_err(&pdev->dev, "can't enable device\n");
 191                goto err;
 192        }
 193
 194        /* XXX 32-bit addressing only */
 195        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 196        if (ret) {
 197                dev_err(&pdev->dev, "32-bit DMA not available\n");
 198                goto err_dis;
 199        }
 200
 201        /*
 202         * Cache line size is used to size and align various
 203         * structures used to communicate with the hardware.
 204         */
 205        pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
 206        if (csz == 0) {
 207                /*
 208                 * Linux 2.4.18 (at least) writes the cache line size
 209                 * register as a 16-bit wide register which is wrong.
 210                 * We must have this setup properly for rx buffer
 211                 * DMA to work so force a reasonable value here if it
 212                 * comes up zero.
 213                 */
 214                csz = L1_CACHE_BYTES >> 2;
 215                pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
 216        }
 217        /*
 218         * The default setting of latency timer yields poor results,
 219         * set it to the value used by other systems.  It may be worth
 220         * tweaking this setting more.
 221         */
 222        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
 223
 224        /* Enable bus mastering */
 225        pci_set_master(pdev);
 226
 227        /*
 228         * Disable the RETRY_TIMEOUT register (0x41) to keep
 229         * PCI Tx retries from interfering with C3 CPU state.
 230         */
 231        pci_write_config_byte(pdev, 0x41, 0);
 232
 233        ret = pci_request_region(pdev, 0, "ath5k");
 234        if (ret) {
 235                dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
 236                goto err_dis;
 237        }
 238
 239        mem = pci_iomap(pdev, 0, 0);
 240        if (!mem) {
 241                dev_err(&pdev->dev, "cannot remap PCI memory region\n");
 242                ret = -EIO;
 243                goto err_reg;
 244        }
 245
 246        /*
 247         * Allocate hw (mac80211 main struct)
 248         * and hw->priv (driver private data)
 249         */
 250        hw = ieee80211_alloc_hw(sizeof(*ah), &ath5k_hw_ops);
 251        if (hw == NULL) {
 252                dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
 253                ret = -ENOMEM;
 254                goto err_map;
 255        }
 256
 257        dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
 258
 259        ah = hw->priv;
 260        ah->hw = hw;
 261        ah->pdev = pdev;
 262        ah->dev = &pdev->dev;
 263        ah->irq = pdev->irq;
 264        ah->devid = id->device;
 265        ah->iobase = mem; /* So we can unmap it on detach */
 266
 267        /* Initialize */
 268        ret = ath5k_init_ah(ah, &ath_pci_bus_ops);
 269        if (ret)
 270                goto err_free;
 271
 272        /* Set private data */
 273        pci_set_drvdata(pdev, hw);
 274
 275        return 0;
 276err_free:
 277        ieee80211_free_hw(hw);
 278err_map:
 279        pci_iounmap(pdev, mem);
 280err_reg:
 281        pci_release_region(pdev, 0);
 282err_dis:
 283        pci_disable_device(pdev);
 284err:
 285        return ret;
 286}
 287
 288static void
 289ath5k_pci_remove(struct pci_dev *pdev)
 290{
 291        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 292        struct ath5k_hw *ah = hw->priv;
 293
 294        ath5k_deinit_ah(ah);
 295        pci_iounmap(pdev, ah->iobase);
 296        pci_release_region(pdev, 0);
 297        pci_disable_device(pdev);
 298        ieee80211_free_hw(hw);
 299}
 300
 301#ifdef CONFIG_PM_SLEEP
 302static int ath5k_pci_suspend(struct device *dev)
 303{
 304        struct pci_dev *pdev = to_pci_dev(dev);
 305        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 306        struct ath5k_hw *ah = hw->priv;
 307
 308        ath5k_led_off(ah);
 309        return 0;
 310}
 311
 312static int ath5k_pci_resume(struct device *dev)
 313{
 314        struct pci_dev *pdev = to_pci_dev(dev);
 315        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 316        struct ath5k_hw *ah = hw->priv;
 317
 318        /*
 319         * Suspend/Resume resets the PCI configuration space, so we have to
 320         * re-disable the RETRY_TIMEOUT register (0x41) to keep
 321         * PCI Tx retries from interfering with C3 CPU state
 322         */
 323        pci_write_config_byte(pdev, 0x41, 0);
 324
 325        ath5k_led_enable(ah);
 326        return 0;
 327}
 328
 329static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume);
 330#define ATH5K_PM_OPS    (&ath5k_pm_ops)
 331#else
 332#define ATH5K_PM_OPS    NULL
 333#endif /* CONFIG_PM_SLEEP */
 334
 335static struct pci_driver ath5k_pci_driver = {
 336        .name           = KBUILD_MODNAME,
 337        .id_table       = ath5k_pci_id_table,
 338        .probe          = ath5k_pci_probe,
 339        .remove         = ath5k_pci_remove,
 340        .driver.pm      = ATH5K_PM_OPS,
 341};
 342
 343module_pci_driver(ath5k_pci_driver);
 344
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.